{
  "openapi": "3.1.0",
  "info": {
    "title": "FabTally OnChain — read-only crypto safety & tax API",
    "version": "1.0.0",
    "description": "Pay-once, no-subscription read-only crypto utilities. Flagship: one-off wallet PnL / tax-CSV export. Plus human-readable transaction decoding and free token-safety / approval teasers. Settlement via x402 (USDC on Base) or a prepaid X-FabTally-Key credit. Informational only.",
    "x-guidance": "Paid JSON endpoints (x402, USDC on Base): POST /v1/pnl-export {address, chains?, year?, method?} ($3 one-off) returns realized PnL + a downloadable CSV; POST /v1/decode {chain, tx_hash | to+calldata} ($0.01) decodes a call to plain English. Free teasers: /v1/pnl-export/free, /v1/token-safety/free, /v1/approvals/free, /v1/decode/free. Unpaid paid-calls return an x402 402 challenge; pay and retry. Humans can use a prepaid X-FabTally-Key header instead. Read-only — never holds funds or signs.",
    "contact": {
      "email": "hello@fabtally.com"
    }
  },
  "servers": [
    {
      "url": "https://onchain.fabtally.com"
    }
  ],
  "paths": {
    "/agent/overview": {
      "get": {
        "operationId": "overview",
        "summary": "Capabilities, pricing, payment info (free)",
        "tags": [
          "Discovery"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Overview"
          }
        }
      }
    },
    "/v1/pnl-export": {
      "post": {
        "operationId": "pnl_export",
        "summary": "Wallet PnL / tax-CSV export (paid, $3 one-off, USDC on Base)",
        "tags": [
          "Paid"
        ],
        "description": "One-off wallet PnL / tax-CSV export. Give one address (Ethereum + Base), get realized gains via FIFO/LIFO cost-basis lot matching over full on-chain transfer history, each leg priced in historical USD, returned as a downloadable CSV + JSON summary. Pay once — no annual subscription. Informational only, not tax advice. Read-only, stateless, no custody.",
        "x-payment-info": {
          "price": {
            "mode": "fixed",
            "currency": "USD",
            "amount": "3.000000"
          },
          "protocols": [
            {
              "x402": {
                "scheme": "exact",
                "network": "eip155:8453",
                "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
                "maxAmountRequired": "3000000",
                "payTo": "0xccB5d25C698FdfdaA7B21d54088774cF512A90e3",
                "resource": "https://onchain.fabtally.com/v1/pnl-export",
                "facilitator": "https://facilitator.daydreams.systems",
                "maxTimeoutSeconds": 120
              }
            }
          ]
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "address"
                ],
                "properties": {
                  "address": {
                    "type": "string",
                    "description": "0x wallet address to export."
                  },
                  "chains": {
                    "type": "string",
                    "description": "Comma list: ethereum,base (or use single `chain`). Default both."
                  },
                  "chain": {
                    "type": "string",
                    "description": "Single chain alias (ethereum | base)."
                  },
                  "year": {
                    "type": "integer",
                    "description": "Optional 4-digit tax year to filter disposals."
                  },
                  "method": {
                    "type": "string",
                    "enum": [
                      "FIFO",
                      "LIFO"
                    ],
                    "description": "Cost-basis method. Default FIFO."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Result",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad input (never charged)"
          },
          "402": {
            "description": "Payment Required (x402 v2 challenge)"
          }
        }
      }
    },
    "/v1/pnl-export/free": {
      "post": {
        "operationId": "pnl_export_free",
        "summary": "PnL export preview — totals + first 5 disposals (FREE)",
        "tags": [
          "Free"
        ],
        "security": [],
        "description": "PnL export preview — totals + first 5 disposals (FREE)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "address"
                ],
                "properties": {
                  "address": {
                    "type": "string",
                    "description": "0x wallet address to export."
                  },
                  "chains": {
                    "type": "string",
                    "description": "Comma list: ethereum,base (or use single `chain`). Default both."
                  },
                  "chain": {
                    "type": "string",
                    "description": "Single chain alias (ethereum | base)."
                  },
                  "year": {
                    "type": "integer",
                    "description": "Optional 4-digit tax year to filter disposals."
                  },
                  "method": {
                    "type": "string",
                    "enum": [
                      "FIFO",
                      "LIFO"
                    ],
                    "description": "Cost-basis method. Default FIFO."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Free result",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/v1/decode": {
      "post": {
        "operationId": "decode",
        "summary": "Human-readable tx / call decode (paid, $0.01 USDC on Base)",
        "tags": [
          "Paid"
        ],
        "description": "Read-only human-readable decode of a transaction or contract call (by tx_hash, or by to+calldata): resolves the ABI, names the function, describes what it does in plain English, and labels each parameter address (contract / known-malicious / token). For pre-sign safety.",
        "x-payment-info": {
          "price": {
            "mode": "fixed",
            "currency": "USD",
            "amount": "0.010000"
          },
          "protocols": [
            {
              "x402": {
                "scheme": "exact",
                "network": "eip155:8453",
                "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
                "maxAmountRequired": "10000",
                "payTo": "0xccB5d25C698FdfdaA7B21d54088774cF512A90e3",
                "resource": "https://onchain.fabtally.com/v1/decode",
                "facilitator": "https://facilitator.daydreams.systems",
                "maxTimeoutSeconds": 60
              }
            }
          ]
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "chain"
                ],
                "properties": {
                  "chain": {
                    "type": "string",
                    "description": "ethereum | base | bsc | polygon | arbitrum | optimism."
                  },
                  "tx_hash": {
                    "type": "string",
                    "description": "0x… tx hash (decode a mined tx)."
                  },
                  "to": {
                    "type": "string",
                    "description": "0x… contract (with calldata)."
                  },
                  "calldata": {
                    "type": "string",
                    "description": "0x… ABI-encoded call data (with to)."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Result",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Bad input (never charged)"
          },
          "402": {
            "description": "Payment Required (x402 v2 challenge)"
          }
        }
      }
    },
    "/v1/decode/free": {
      "post": {
        "operationId": "decode_free",
        "summary": "Decode — method + params teaser (FREE)",
        "tags": [
          "Free"
        ],
        "security": [],
        "description": "Decode — method + params teaser (FREE)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "chain"
                ],
                "properties": {
                  "chain": {
                    "type": "string",
                    "description": "ethereum | base | bsc | polygon | arbitrum | optimism."
                  },
                  "tx_hash": {
                    "type": "string",
                    "description": "0x… tx hash (decode a mined tx)."
                  },
                  "to": {
                    "type": "string",
                    "description": "0x… contract (with calldata)."
                  },
                  "calldata": {
                    "type": "string",
                    "description": "0x… ABI-encoded call data (with to)."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Free result",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/v1/token-safety/free": {
      "post": {
        "operationId": "token_safety_free",
        "summary": "Token safety — basic flags + verdict (FREE)",
        "tags": [
          "Free"
        ],
        "security": [],
        "description": "Token safety — basic flags + verdict (FREE)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "address",
                  "chain"
                ],
                "properties": {
                  "address": {
                    "type": "string"
                  },
                  "chain": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Free result",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/v1/approvals/free": {
      "post": {
        "operationId": "approvals_free",
        "summary": "Approvals — counts + top-3 risks (FREE)",
        "tags": [
          "Free"
        ],
        "security": [],
        "description": "Approvals — counts + top-3 risks (FREE)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "address",
                  "chain"
                ],
                "properties": {
                  "address": {
                    "type": "string"
                  },
                  "chain": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Free result",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/health": {
      "get": {
        "operationId": "health",
        "summary": "Health (free)",
        "tags": [
          "Discovery"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
  }
}