Bitrovas L402 Services
api.bitrovas.ch
· Bitrovas
Pay-per-request Bitcoin and data utility services over HTTP with L402 (Lightning). No account, no API key; inputs are processed in memory and not stored.
api.bitrovas.ch via a single DNS TXT record to add the
verified by owner badge, embed an Agenstry badge on your README, and earn back the missing conformance points listed below.
Dispute or improve this rating
C
Conformance score: 64/100
C-grade: usable but has clear conformance issues, review the breakdown below.
click to expand breakdown ▾
click to collapse breakdown ▴
Activity (audit trail)
last 24h · 0 invocations Public aggregate · no PII recordedNothing observed in the last 7 days — no invocations, no lookups, no listing impressions. Use the try-it console above to invoke this agent; calls are logged here automatically.
Card history
1 snapshot Every change toagent-card.json
| Captured | Hash | Snapshot |
|---|---|---|
| 2026-10-17 14:22:33 current | d5ccd90b0786… |
view → |
Try it
Send a message to this agent live. Your prompt is proxied through Agenstry.
Endpoints
| Agent card | https://api.bitrovas.ch/.well-known/agent-card.json |
| Provider | https://bitcoin.bitrovas.ch |
| Docs | https://api.bitrovas.ch/docs |
Skills · 7 declared by this agent
These skills are declared by the agent. A taxonomy link appears only when we can classify a skill confidently.
Pre-sign check of an unsigned Bitcoin PSBT: recipients, amounts, change, fee/sat-vB, RBF, sighash, missing UTXO info, dust, address-poisoning lookalikes. Verdic…
Address-poisoning check: compares the address you are about to send to (used) with the address you know (expected) and detects lookalike/vanity patterns for Bit…
Validate and repair a JSON array of flat records (max 1000 rows): syntax repair (trailing commas, code fences, Python literals), whitespace trim, NULL normaliza…
Watch-only address derivation from xpub/ypub/zpub/tpub or an output descriptor: receive + change addresses (configurable gap, max 1000) and ownership check of g…
Technical offline check of a Swiss QR-bill (SPC payload) or IBAN + reference: format, IBAN checksum, CH/LI, QR-IBAN vs reference type (QRR/SCOR/NON), QR-referen…
Validate CSV, YAML, XML, TOML or JSON (data max 1 MiB, 1M elements). Price: 10 sats + 1 sat per started KB of data, free quote at POST /v1/formatcheck/quote. Co…
Bitcoin timestamp for a SHA-256 hash or Nostr event id via OpenTimestamps. Returns a pending .ots proof (base64) immediately; the free GET /v1/timestamp/<id> re…
Health · last 1 probes
Similar agents embedding-nearest
Embed your Agenstry badge
Paste any of these into your README, agent card, or marketing page. Each badge auto-updates and links back to this page.
Markdown / HTML snippets
[](https://agenstry.com/agents/api.bitrovas.ch) [](https://agenstry.com/agents/api.bitrovas.ch) [](https://agenstry.com/agents/api.bitrovas.ch) [](https://agenstry.com/agents/api.bitrovas.ch)
Audit-grade evidence bundle
JSON snapshot for vendor-review files. Add ?sign=true for a JWS-signed envelope verifiable against
our JWKS. See the methodology.
Raw agent card JSON
{
"name": "Bitrovas L402 Services",
"description": "Pay-per-request Bitcoin and data utility services over HTTP with L402 (Lightning). No account, no API key; inputs are processed in memory and not stored.",
"supportedInterfaces": [
{
"url": "https://api.bitrovas.ch/a2a",
"protocolBinding": "JSONRPC",
"protocolVersion": "1.0"
}
],
"provider": {
"organization": "Bitrovas",
"url": "https://bitcoin.bitrovas.ch"
},
"version": "1.0.0",
"documentationUrl": "https://api.bitrovas.ch/docs",
"capabilities": {
"streaming": false,
"pushNotifications": false,
"extensions": [
{
"uri": "https://a2a-registry.org/extensions/registry/v1",
"description": "L402 payment. A2A: SendMessage returns a task in TASK_STATE_INPUT_REQUIRED with a DataPart {l402: {macaroon, token, invoice, amountSats, paymentHash}}; after paying, SendMessage with the same taskId and {l402: {token, preimage}} completes the task. REST: each skill endpoint answers HTTP 402 with a Lightning (BOLT11) invoice and a macaroon in WWW-Authenticate; repeat the request with 'Authorization: L402 <macaroon>:<preimage>'. Machine-readable price list: https://api.bitrovas.ch/.well-known/l402-services",
"required": false,
"params": {
"payment": {
"model": "paid",
"protocols": [
"lightning-invoice"
],
"direction": "inbound",
"rails": [
{
"network": "lightning",
"token": "BTC",
"type": "crypto",
"protocol": "lightning-invoice",
"settlementTime": "instant"
}
],
"skills": [
{
"skillId": "psbtcheck",
"price": "21",
"currency": "sats",
"unit": "request"
},
{
"skillId": "poisoncheck",
"price": "21",
"currency": "sats",
"unit": "request"
},
{
"skillId": "jsonrepair",
"price": "10",
"currency": "sats",
"unit": "request"
},
{
"skillId": "walletaddr",
"price": "21",
"currency": "sats",
"unit": "request"
},
{
"skillId": "qrbill",
"price": "10",
"currency": "sats",
"unit": "request"
},
{
"skillId": "formatcheck",
"price": "11",
"currency": "sats",
"unit": "request"
},
{
"skillId": "timestamp",
"price": "21",
"currency": "sats",
"unit": "request"
}
],
"meta": {
"scheme": "L402",
"unit": "sats",
"directory": "https://api.bitrovas.ch/.well-known/l402-services",
"auth_header": "Authorization: L402 <macaroon>:<preimage>",
"refund_policy": "invalid input is rejected (REST HTTP 400, A2A TASK_STATE_REJECTED) before an invoice is created",
"formatcheck_pricing": "10 sats + 1 sat per started KB (1024 bytes) of data, max 1 MiB; free quote POST https://api.bitrovas.ch/v1/formatcheck/quote"
}
}
}
}
]
},
"defaultInputModes": [
"application/json"
],
"defaultOutputModes": [
"application/json"
],
"skills": [
{
"id": "psbtcheck",
"name": "Bitrovas PSBT-Check",
"description": "Pre-sign check of an unsigned Bitcoin PSBT: recipients, amounts, change, fee/sat-vB, RBF, sighash, missing UTXO info, dust, address-poisoning lookalikes. Verdict ok|warn|danger, JSON + text DE/EN. Never signs or broadcasts. Endpoint: POST https://api.bitrovas.ch/v1/psbtcheck (also POST https://api.bitrovas.ch/v1/psbtcheck/task with {\"task\": \"<free text>\"}). Price: 21 sats per request, paid via L402 (Lightning). Input (application/json): psbt: unsigned PSBT v0, base64 or hex (required); expected_address: optional; expected_amount_sats: optional integer; network: optional mainnet|testnet|signet|regtest. Output (application/json): service, verdict ok|warn|danger, result (recipients, amounts, change, fee, findings), text_de, text_en. A2A (JSON-RPC, https://api.bitrovas.ch/a2a): SendMessage with a DataPart {\"skill\": \"psbtcheck\", \"input\": {...same fields as REST...}}; the task answers TASK_STATE_INPUT_REQUIRED with a DataPart {\"l402\": {macaroon, token, invoice, amountSats, paymentHash}}; pay, then SendMessage with the same taskId and a DataPart {\"l402\": {\"token\": ..., \"preimage\": ...}} to get TASK_STATE_COMPLETED with the result as artifact (DataPart).",
"tags": [
"bitrovas",
"l402",
"lightning",
"psbtcheck"
],
"examples": [
"{\"skill\":\"psbtcheck\",\"input\":{\"psbt\":\"cHNidP8B...\",\"expected_address\":\"bc1q...\",\"expected_amount_sats\":50000}}",
"REST: POST https://api.bitrovas.ch/v1/psbtcheck with a JSON body; answer the 402 invoice, then repeat with Authorization: L402 <token>:<preimage>"
],
"inputModes": [
"application/json"
],
"outputModes": [
"application/json"
]
},
{
"id": "poisoncheck",
"name": "Bitrovas PoisonCheck",
"description": "Address-poisoning check: compares the address you are about to send to (used) with the address you know (expected) and detects lookalike/vanity patterns for Bitcoin, EVM and Tron. Level poison|review|clear, JSON + text DE/EN. Single 21 sats; batch up to 50 addresses 21 + 5 sats per address. Pattern, not proof; not a send approval. Endpoint: POST https://api.bitrovas.ch/v1/poisoncheck (also POST https://api.bitrovas.ch/v1/poisoncheck/task with {\"task\": \"<free text>\"}). Price: 21 sats per request, paid via L402 (Lightning). Input (application/json): used: address to check (string) \u2013 or list of up to 50 addresses for batch; expected: address you know is correct (string; for batch also a list of the same length); pricing: {'single': 21, 'batch': '21 + 5 per address (max 50)'}. Output (application/json): verdict ok|warn|danger per address, similarity findings vs. expected/known addresses, text DE/EN. A2A (JSON-RPC, https://api.bitrovas.ch/a2a): SendMessage with a DataPart {\"skill\": \"poisoncheck\", \"input\": {...same fields as REST...}}; the task answers TASK_STATE_INPUT_REQUIRED with a DataPart {\"l402\": {macaroon, token, invoice, amountSats, paymentHash}}; pay, then SendMessage with the same taskId and a DataPart {\"l402\": {\"token\": ..., \"preimage\": ...}} to get TASK_STATE_COMPLETED with the result as artifact (DataPart).",
"tags": [
"bitrovas",
"l402",
"lightning",
"poisoncheck"
],
"examples": [
"{\"skill\":\"poisoncheck\",\"input\":{\"used\":\"bc1q...\",\"expected\":\"bc1q...\"}}",
"REST: POST https://api.bitrovas.ch/v1/poisoncheck with a JSON body; answer the 402 invoice, then repeat with Authorization: L402 <token>:<preimage>"
],
"inputModes": [
"application/json"
],
"outputModes": [
"application/json"
]
},
{
"id": "jsonrepair",
"name": "Bitrovas JSON Validate & Repair",
"description": "Validate and repair a JSON array of flat records (max 1000 rows): syntax repair (trailing commas, code fences, Python literals), whitespace trim, NULL normalization, duplicate removal, optional type standardization, e-mail check and JSON Schema (2020-12) validation with flag|drop. Returns cleaned JSON + machine-readable report. Deterministic; no data stored. Endpoint: POST https://api.bitrovas.ch/v1/jsonrepair (also POST https://api.bitrovas.ch/v1/jsonrepair/task with {\"task\": \"<free text>\"}). Price: 10 sats per request, paid via L402 (Lightning). Input (application/json): data: JSON array of flat objects, or {\"records\": [...]}, or a JSON string to repair (required, max 1000 rows); json_schema: optional JSON Schema 2020-12 applied per row; json_schema_action: optional flag|drop (default flag); options: optional DataCleanBot options, e.g. {\"operations\": [...], \"schema\": {col: type}, \"dedupe_keys\": [...]}. Output (application/json): repaired/cleaned JSON data plus a list of applied fixes. A2A (JSON-RPC, https://api.bitrovas.ch/a2a): SendMessage with a DataPart {\"skill\": \"jsonrepair\", \"input\": {...same fields as REST...}}; the task answers TASK_STATE_INPUT_REQUIRED with a DataPart {\"l402\": {macaroon, token, invoice, amountSats, paymentHash}}; pay, then SendMessage with the same taskId and a DataPart {\"l402\": {\"token\": ..., \"preimage\": ...}} to get TASK_STATE_COMPLETED with the result as artifact (DataPart).",
"tags": [
"bitrovas",
"l402",
"lightning",
"jsonrepair"
],
"examples": [
"{\"skill\":\"jsonrepair\",\"input\":{\"data\":\"[{'a': 1,},]\"}}",
"REST: POST https://api.bitrovas.ch/v1/jsonrepair with a JSON body; answer the 402 invoice, then repeat with Authorization: L402 <token>:<preimage>"
],
"inputModes": [
"application/json"
],
"outputModes": [
"application/json"
]
},
{
"id": "walletaddr",
"name": "Bitrovas Wallet-Adressen",
"description": "Watch-only address derivation from xpub/ypub/zpub/tpub or an output descriptor: receive + change addresses (configurable gap, max 1000) and ownership check of given addresses with derivation path. Offline, nothing stored. Private keys/seeds are rejected. Endpoint: POST https://api.bitrovas.ch/v1/walletaddr (also POST https://api.bitrovas.ch/v1/walletaddr/task with {\"task\": \"<free text>\"}). Price: 21 sats per request, paid via L402 (Lightning). Input (application/json): xpub: xpub/ypub/zpub/tpub/upub/vpub (account level) \u2013 or \u2013; descriptor: output descriptor with * (e.g. wpkh([fp/84h/0h/0h]xpub/<0;1>/*)); addresses: optional list of addresses to check (max 50); script: optional override for xpub/tpub: p2pkh|p2wpkh|p2sh-p2wpkh|p2tr; gap: optional, addresses per chain (default 20, max 1000). Output (application/json): derived addresses (index, address, path), optional match result for a searched address. A2A (JSON-RPC, https://api.bitrovas.ch/a2a): SendMessage with a DataPart {\"skill\": \"walletaddr\", \"input\": {...same fields as REST...}}; the task answers TASK_STATE_INPUT_REQUIRED with a DataPart {\"l402\": {macaroon, token, invoice, amountSats, paymentHash}}; pay, then SendMessage with the same taskId and a DataPart {\"l402\": {\"token\": ..., \"preimage\": ...}} to get TASK_STATE_COMPLETED with the result as artifact (DataPart).",
"tags": [
"bitrovas",
"l402",
"lightning",
"walletaddr"
],
"examples": [
"{\"skill\":\"walletaddr\",\"input\":{\"xpub\":\"zpub...\",\"addresses\":[\"bc1q...\"]}}",
"REST: POST https://api.bitrovas.ch/v1/walletaddr with a JSON body; answer the 402 invoice, then repeat with Authorization: L402 <token>:<preimage>"
],
"inputModes": [
"application/json"
],
"outputModes": [
"application/json"
]
},
{
"id": "qrbill",
"name": "Bitrovas QR-Rechnung-Check",
"description": "Technical offline check of a Swiss QR-bill (SPC payload) or IBAN + reference: format, IBAN checksum, CH/LI, QR-IBAN vs reference type (QRR/SCOR/NON), QR-reference mod10, ISO 11649, amount/currency, mandatory fields, lengths, character set. Optional: compares the bill's IBAN with expected supplier IBAN(s) supplied by the customer (plain or SHA-256); mismatch = danger. Only checks structure and this comparison, not whether a bill is genuine. Verdict ok|warn|danger, DE/EN + JSON. Nothing stored or logged. Endpoint: POST https://api.bitrovas.ch/v1/qrbill (also POST https://api.bitrovas.ch/v1/qrbill/task with {\"task\": \"<free text>\"}). Price: 10 sats per request, paid via L402 (Lightning). Input (application/json): payload: QR-bill SPC payload text (all lines) \u2013 or \u2013; iban: IBAN; reference: optional QRR/SCOR reference; amount: optional; currency: optional CHF|EUR; expected_iban: optional: expected supplier IBAN or list (max 20); normalized (no spaces, uppercase); expected_iban_sha256: optional: hex SHA-256 of normalized IBAN (no spaces, uppercase, ASCII) or list. Output (application/json): verdict ok|warn|danger, list of technical findings, IBAN comparison result if expected IBANs were supplied, text DE/EN. A2A (JSON-RPC, https://api.bitrovas.ch/a2a): SendMessage with a DataPart {\"skill\": \"qrbill\", \"input\": {...same fields as REST...}}; the task answers TASK_STATE_INPUT_REQUIRED with a DataPart {\"l402\": {macaroon, token, invoice, amountSats, paymentHash}}; pay, then SendMessage with the same taskId and a DataPart {\"l402\": {\"token\": ..., \"preimage\": ...}} to get TASK_STATE_COMPLETED with the result as artifact (DataPart).",
"tags": [
"bitrovas",
"l402",
"lightning",
"qrbill"
],
"examples": [
"{\"skill\":\"qrbill\",\"input\":{\"iban\":\"CH4431999123000889012\",\"expected_iban\":\"CH4431999123000889012\"}}",
"REST: POST https://api.bitrovas.ch/v1/qrbill with a JSON body; answer the 402 invoice, then repeat with Authorization: L402 <token>:<preimage>"
],
"inputModes": [
"application/json"
],
"outputModes": [
"application/json"
]
},
{
"id": "formatcheck",
"name": "Bitrovas FormatCheck",
"description": "Validate CSV, YAML, XML, TOML or JSON (data max 1 MiB, 1M elements). Price: 10 sats + 1 sat per started KB of data, free quote at POST /v1/formatcheck/quote. Converts to JSON (or flat JSON -> CSV); optional JSON Schema 2020-12 validation (local $ref only). Safe parsers (defusedxml, yaml.safe_load, tomllib), size and time limits, in-memory only. Invalid input = free 400 with error position. Nothing stored or logged. Endpoint: POST https://api.bitrovas.ch/v1/formatcheck (also POST https://api.bitrovas.ch/v1/formatcheck/task with {\"task\": \"<free text>\"}). Price: from 11 sats (10 + 1 per started KB), paid via L402 (Lightning). Input (application/json): data: input text (required, UTF-8, max 1 MiB); format: csv|yaml|xml|toml|json (required); action: optional validate (default) | to_json | to_csv (to_csv: format json, flat records); json_schema: optional JSON Schema 2020-12 for the parsed document (local $ref only, max 8 KB). Output (application/json): valid true|false, errors (line/path, message), converted output (JSON or CSV), optional JSON-Schema errors. A2A (JSON-RPC, https://api.bitrovas.ch/a2a): SendMessage with a DataPart {\"skill\": \"formatcheck\", \"input\": {...same fields as REST...}}; the task answers TASK_STATE_INPUT_REQUIRED with a DataPart {\"l402\": {macaroon, token, invoice, amountSats, paymentHash}}; pay, then SendMessage with the same taskId and a DataPart {\"l402\": {\"token\": ..., \"preimage\": ...}} to get TASK_STATE_COMPLETED with the result as artifact (DataPart). Max 1 MiB data; free price quote: POST https://api.bitrovas.ch/v1/formatcheck/quote.",
"tags": [
"bitrovas",
"l402",
"lightning",
"formatcheck"
],
"examples": [
"{\"skill\":\"formatcheck\",\"input\":{\"format\":\"yaml\",\"data\":\"a: 1\",\"action\":\"to_json\"}}",
"REST: POST https://api.bitrovas.ch/v1/formatcheck with a JSON body; answer the 402 invoice, then repeat with Authorization: L402 <token>:<preimage>"
],
"inputModes": [
"application/json"
],
"outputModes": [
"application/json"
]
},
{
"id": "timestamp",
"name": "Bitrovas Zeitstempel (OpenTimestamps)",
"description": "Bitcoin timestamp for a SHA-256 hash or Nostr event id via OpenTimestamps. Returns a pending .ots proof (base64) immediately; the free GET /v1/timestamp/<id> returns the upgraded proof and block height after confirmation (usually 1\u201312 h). Only the hash is sent, never the file. Endpoint: POST https://api.bitrovas.ch/v1/timestamp (also POST https://api.bitrovas.ch/v1/timestamp/task with {\"task\": \"<free text>\"}). Price: 21 sats per request, paid via L402 (Lightning). Input (application/json): hash: SHA-256 hex (64) of your file \u2013 or \u2013; event_id: Nostr event id (hex, note1\u2026, nevent1\u2026); status: GET /v1/timestamp/<id> (free). Output (application/json): id, pending OpenTimestamps proof (.ots, base64), status_url (free GET /v1/timestamp/<id> for the upgraded proof). A2A (JSON-RPC, https://api.bitrovas.ch/a2a): SendMessage with a DataPart {\"skill\": \"timestamp\", \"input\": {...same fields as REST...}}; the task answers TASK_STATE_INPUT_REQUIRED with a DataPart {\"l402\": {macaroon, token, invoice, amountSats, paymentHash}}; pay, then SendMessage with the same taskId and a DataPart {\"l402\": {\"token\": ..., \"preimage\": ...}} to get TASK_STATE_COMPLETED with the result as artifact (DataPart).",
"tags": [
"bitrovas",
"l402",
"lightning",
"timestamp"
],
"examples": [
"{\"skill\":\"timestamp\",\"input\":{\"hash\":\"<sha256 hex, 64 chars>\"}}",
"REST: POST https://api.bitrovas.ch/v1/timestamp with a JSON body; answer the 402 invoice, then repeat with Authorization: L402 <token>:<preimage>"
],
"inputModes": [
"application/json"
],
"outputModes": [
"application/json"
]
}
]
}