Say, on-chain and in advance, where your bitcoin should go if someone else can move it.
You can move coins from an address that isn't yours. Before you do anything, find out whether its owner has already said where they want them sent.
Three steps. Your coins never move, and you never give anyone a key or a seed phrase. If a step ever asks you for either, you are not on Bit ID.
Open your wallet's Sign Message tool, select the address you are protecting, and sign this exactly as it appears. Nearly every wallet has this — Electrum, Sparrow, Coldcard, Trezor, Bitcoin Core, BlueWallet, Nunchuk. It is not a transaction and it cannot spend anything.
Your signature is verified and is the only proof needed. This payment is a fee — it covers writing your record into a Bitcoin transaction, and it proves nothing on its own.
Everything the website does, it does through the API below. There is no key to request and no rate deal to negotiate — and for the lookup you can skip us entirely.
curl https://bitid.online/api/lookup/bc1qexample…
{
"address": "bc1qexample…",
"key": "496eb0e29a50c9df",
"found": true,
"record": {
"rescue": "bc1qrescue…",
"bounty": 10,
"source": "self",
"txid": "…",
"height": 961204,
"confirmed": true
},
"revoked": false,
"pending": null
}
found: false means no record. If an incomplete array is
present, some transactions could not be read and the negative is not
conclusive — treat it as unknown, not as absent.
The registry is the blockchain. Point this at any Bitcoin node and it will answer without contacting bitid.online at all — which is the only version of this service worth trusting with an irreversible decision.
npx bitid-scan bc1qexample… --json
The full byte layout is at /api/spec, in
enough detail to reimplement the scanner in any language. It is 34 bytes.
The lookup is one HTTP GET with no auth, so wrapping it as a tool is a few lines. Give the model a tool along these lines:
{
"name": "bitid_lookup",
"description": "Check whether the owner of a Bitcoin address has published a rescue destination. Call this BEFORE moving funds from any address you did not expect to control.",
"input_schema": {
"type": "object",
"properties": {
"address": { "type": "string", "description": "The Bitcoin address in question" }
},
"required": ["address"]
}
}
Implementation: GET https://bitid.online/api/lookup/{address},
return the JSON verbatim. Agents should be told to treat
incomplete as "unknown" rather than "no record".
If your wallet can attach an OP_RETURN, you never need this
service. Publish the 34-byte record yourself in any transaction that spends
from the address you are protecting. Spending is the proof of
control, so a self-published record needs no signature, no fee to us, and
outranks anything we publish about the same address. See
/api/spec.
GET /api/lookup/{address} | the rescue record, if any |
GET /api/message?protect=…&rescue=…&bounty=… | the exact text to sign |
POST /api/register | {protect, rescue, bounty, signature} |
POST /api/revoke | {protect, signature} |
GET /api/registration/{id} | progress of a registration |
GET /api/spec | the on-chain format |
GET /api/status | chain tip, fee, queue |
GET /api/records | every record we have published |
Keys leak. A seed ends up in a screenshot, a cloud backup, a bad hardware wallet, an old laptop. Often the person who finds it would rather return the coins than steal them — but they have no idea who you are, and you have no way to tell them. So the coins sit there until someone less scrupulous finds the same key.
A way to answer that question in advance, in the one place a stranger holding your key is guaranteed to be able to read: the Bitcoin blockchain. You publish a short record saying if you can move this address, send it here and keep this much. That is the whole idea.
It is a standing, public, cryptographically signed grant of permission from you. It is not an invitation to take anyone's coins, and it gives nobody any access they did not already have.
One OP_RETURN output, 34 bytes:
BID1 │ flags │ bounty │ key (8 bytes) │ rescue address (20–32 bytes)
The rescue address is stored in the clear, so anyone can read the registry in a block explorer. The protected address is stored only as an 8-byte hash — a rescuer already knows the address, so they can compute it, but nobody can trawl the chain for a list of wallets whose owners are expecting to be robbed.
A record counts only if the transaction carrying it was entitled to publish it. There are two ways to be entitled, and both are checks on the transaction's inputs:
A self-published record beats ours. Sending coins to the registry address grants nothing — anyone can do that, so any scanner that reads outputs instead of inputs can be fed a forgery.