{
  "openapi": "3.1.0",
  "info": {
    "title": "PayeeGuard",
    "version": "0.1.0",
    "summary": "Deterministic payment-destination preflight for agents, paid per call.",
    "description": "PayeeGuard checks where the money is about to go, while that is still a decision rather than a fact. It verifies the EIP-55 checksum a mixed-case address carries, compares the destination against the address you said you expected and reports the exact hex positions that differ, recognises the ground look-alikes used in address-poisoning attacks by their shared prefix and suffix rather than by edit distance alone, blocks burn sinks, precompiles and a token contract offered as its own payee, and says whether the destination can receive the asset at all. There is no model anywhere in it, and most of it is exact arithmetic on twenty bytes. Where the chain is needed and cannot answer, it returns unknown, because a confident guess about an irreversible transfer is worse than no answer.",
    "contact": {
      "email": "support@schemasure.com"
    },
    "x-policy-version": "2026-09-19"
  },
  "servers": [
    {
      "url": "https://payee.schemasure.com"
    }
  ],
  "paths": {
    "/v1/guard/payee": {
      "post": {
        "operationId": "payeeguard_v1_guard_payee",
        "summary": "Check a payment destination before the transfer becomes irreversible",
        "description": "Pre-flight a Base payment destination before you send. Verifies the EIP-55 checksum, measures distance from an address you expect — catching a mistyped digit and the shared prefix-and-suffix shape of a ground look-alike — flags the zero address, burn sinks and precompiles, refuses a token offered as its own payee, and reports whether the destination can receive the asset. Returns unknown rather than guessing when bytecode does not decide it. Not a judgement of the counterparty.",
        "x-payment-info": {
          "x402Version": 2,
          "scheme": "exact",
          "network": "eip155:8453",
          "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
          "amountAtomic": "10000",
          "priceUsd": 0.01,
          "payTo": "0x9876af0F6D8Ed5155Cd02d1ca56D128601612690",
          "policy": "charge only on a successful, usable result"
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "title": "PayeeGuardRequest",
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "address"
                ],
                "properties": {
                  "address": {
                    "type": "string",
                    "pattern": "^0[xX][0-9a-fA-F]{40}$",
                    "description": "The destination you are about to send to. Send it exactly as you hold it, casing included: the casing is the checksum, and normalising it before you ask destroys the evidence this endpoint checks."
                  },
                  "asset": {
                    "type": "string",
                    "description": "\"native\" for ETH, or an ERC-20 contract address. Defaults to \"native\". The asset decides which receivability question is asked, and they have different answers.",
                    "default": "native"
                  },
                  "expected_address": {
                    "type": "string",
                    "pattern": "^0[xX][0-9a-fA-F]{40}$",
                    "description": "The address you believe the destination should be. Supplying it enables the comparison checks: exact match, case-only difference, small edit distance, and the shared prefix-and-suffix shape of a ground look-alike."
                  },
                  "from": {
                    "type": "string",
                    "pattern": "^0[xX][0-9a-fA-F]{40}$",
                    "description": "The sender, when you have one. Enables the self-send check."
                  }
                }
              },
              "example": {
                "address": "0x7a3D40f7c6B18E5920Ab7C3e5d81f4A04E6F8a0D",
                "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
                "expected_address": "0x7A3D9C1b5e2F4A8d6C0b3E5F7a9D1c2b4e6f8A0d"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful result envelope",
            "content": {
              "application/json": {
                "schema": {
                  "$schema": "https://json-schema.org/draft/2020-12/schema",
                  "title": "PayeeGuardEnvelope",
                  "type": "object",
                  "required": [
                    "ok",
                    "verdict",
                    "confidence",
                    "risk_codes",
                    "evidence",
                    "result",
                    "policy_version",
                    "request_hash",
                    "data_versions",
                    "warnings"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "verdict": {
                      "type": "string",
                      "enum": [
                        "allow",
                        "warn",
                        "block",
                        "unknown"
                      ],
                      "description": "Precedence: block, then unknown, then warn, then allow."
                    },
                    "confidence": {
                      "type": "number",
                      "minimum": 0,
                      "maximum": 1
                    },
                    "risk_codes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Only findings arguing against proceeding. Informational findings stay in evidence."
                    },
                    "evidence": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    },
                    "policy_version": {
                      "type": "string"
                    },
                    "request_hash": {
                      "type": "string",
                      "pattern": "^sha256:[0-9a-f]{64}$"
                    },
                    "warnings": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "data_versions": {
                      "type": "object",
                      "required": [
                        "denylist",
                        "sinks",
                        "bytecode_shapes",
                        "policy",
                        "chain"
                      ]
                    },
                    "result": {
                      "type": "object",
                      "required": [
                        "address",
                        "asset",
                        "checksum",
                        "expected_comparison",
                        "sinks",
                        "destination",
                        "can_receive",
                        "self_send",
                        "denylist_hits",
                        "unresolved",
                        "rpc"
                      ],
                      "properties": {
                        "checksum": {
                          "type": "object",
                          "properties": {
                            "form": {
                              "type": "string",
                              "enum": [
                                "mixed",
                                "uppercase",
                                "lowercase",
                                "caseless"
                              ]
                            },
                            "valid": {
                              "type": [
                                "boolean",
                                "null"
                              ],
                              "description": "null when the address carries no checksum, which is not a failed one."
                            }
                          }
                        },
                        "expected_comparison": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "description": "null when no expected_address was supplied. Absent is not a match.",
                          "properties": {
                            "match": {
                              "type": "string",
                              "enum": [
                                "exact",
                                "case_only",
                                "near_miss",
                                "vanity_collision",
                                "different"
                              ]
                            },
                            "differing_positions": {
                              "type": "array",
                              "items": {
                                "type": "integer"
                              }
                            }
                          }
                        },
                        "destination": {
                          "type": "object",
                          "properties": {
                            "is_contract": {
                              "type": [
                                "boolean",
                                "null"
                              ]
                            },
                            "account_kind": {
                              "type": "string",
                              "enum": [
                                "eoa",
                                "contract",
                                "minimal-proxy",
                                "delegated-eoa",
                                "unknown"
                              ]
                            }
                          }
                        },
                        "can_receive": {
                          "type": "object",
                          "properties": {
                            "value": {
                              "type": [
                                "boolean",
                                "null"
                              ],
                              "description": "null when the bytecode does not decide it. Never guessed in either direction."
                            },
                            "basis": {
                              "type": "string"
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "ok": true,
                  "verdict": "block",
                  "confidence": 1,
                  "risk_codes": [
                    "EXPECTED_ADDRESS_VANITY_COLLISION",
                    "ASSET_EXISTENCE_UNKNOWN"
                  ],
                  "evidence": [
                    {
                      "code": "CHECKSUM_VALID",
                      "severity": "info",
                      "detail": "The destination matches its EIP-55 checksum exactly.",
                      "source": "eip55"
                    },
                    {
                      "code": "EXPECTED_ADDRESS_VANITY_COLLISION",
                      "severity": "critical",
                      "detail": "The destination shares the first 4 and last 8 hex digits with the address you expected while differing throughout the middle. That is the signature of a ground look-alike address, the shape used in address-poisoning attacks, because those are the digits a person checks.",
                      "source": "address-distance",
                      "data": {
                        "match": "vanity_collision",
                        "differing_positions": [
                          4,
                          5,
                          6,
                          7,
                          8,
                          9,
                          10,
                          11,
                          12,
                          13,
                          14,
                          15,
                          16,
                          17,
                          18,
                          20,
                          21,
                          22,
                          23,
                          24,
                          25,
                          26,
                          27,
                          28,
                          29,
                          30,
                          31
                        ],
                        "hamming_distance": 27,
                        "edit_distance": 25,
                        "shared_prefix": 4,
                        "shared_suffix": 8,
                        "expected": "0x7A3D9C1b5e2F4A8d6C0b3E5F7a9D1c2b4e6f8A0d"
                      }
                    },
                    {
                      "code": "RECEIPT_UNCONDITIONAL",
                      "severity": "info",
                      "detail": "An ERC-20 transfer credits a balance in the token's own storage and never calls the destination, so receipt succeeds for any address — contract or wallet, token-aware or not. Whether the destination can later move those units is a property of its own code and is not evaluated here.",
                      "source": "erc20-semantics"
                    },
                    {
                      "code": "ASSET_EXISTENCE_UNKNOWN",
                      "severity": "medium",
                      "detail": "Whether 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 has a deployed token behind it could not be established, so this answer covers the destination but not the asset.",
                      "source": "eth_getCode"
                    }
                  ],
                  "result": {
                    "address": {
                      "input": "0x7a3D40f7c6B18E5920Ab7C3e5d81f4A04E6F8a0D",
                      "canonical": "0x7a3D40f7c6B18E5920Ab7C3e5d81f4A04E6F8a0D",
                      "lowercase": "0x7a3d40f7c6b18e5920ab7c3e5d81f4a04e6f8a0d"
                    },
                    "asset": {
                      "kind": "erc20",
                      "address": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
                      "symbol": null,
                      "decimals": null,
                      "exists": null,
                      "detail": "no RPC configured, so code presence could not be read; no RPC configured, so token metadata could not be read"
                    },
                    "checksum": {
                      "form": "mixed",
                      "valid": true,
                      "canonical": "0x7a3D40f7c6B18E5920Ab7C3e5d81f4A04E6F8a0D",
                      "detail": "matches its EIP-55 checksum exactly"
                    },
                    "expected_comparison": {
                      "match": "vanity_collision",
                      "differing_positions": [
                        4,
                        5,
                        6,
                        7,
                        8,
                        9,
                        10,
                        11,
                        12,
                        13,
                        14,
                        15,
                        16,
                        17,
                        18,
                        20,
                        21,
                        22,
                        23,
                        24,
                        25,
                        26,
                        27,
                        28,
                        29,
                        30,
                        31
                      ],
                      "hamming_distance": 27,
                      "edit_distance": 25,
                      "shared_prefix": 4,
                      "shared_suffix": 8,
                      "expected_canonical": "0x7A3D9C1b5e2F4A8d6C0b3E5F7a9D1c2b4e6f8A0d",
                      "detail": "shares the first 4 and last 8 hex digits with the address you expected while differing throughout the middle. That is the signature of a ground look-alike address, the shape used in address-poisoning attacks, because those are the digits a person checks"
                    },
                    "sinks": {
                      "is_zero_address": false,
                      "is_burn_address": false,
                      "is_precompile": false,
                      "label": null,
                      "detail": "is not the zero address, a known burn sink, or a precompile"
                    },
                    "destination": {
                      "is_contract": null,
                      "code_size": null,
                      "account_kind": "unknown",
                      "forwards_to": null,
                      "detail": "no RPC configured, so code presence could not be read"
                    },
                    "can_receive": {
                      "value": true,
                      "basis": "erc20-balance-mapping",
                      "detail": "An ERC-20 transfer credits a balance in the token's own storage and never calls the destination, so receipt succeeds for any address — contract or wallet, token-aware or not. Whether the destination can later move those units is a property of its own code and is not evaluated here."
                    },
                    "self_send": {
                      "present": false,
                      "from": null,
                      "matches": null,
                      "detail": "No sender was supplied, so the self-send check did not run."
                    },
                    "denylist_hits": [],
                    "unresolved": [
                      "whether 0x7a3D40f7c6B18E5920Ab7C3e5d81f4A04E6F8a0D holds contract code: no RPC configured, so code presence could not be read",
                      "whether 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 is a deployed contract: no RPC configured, so code presence could not be read"
                    ],
                    "rpc": {
                      "configured": false,
                      "endpoints": []
                    }
                  },
                  "policy_version": "2026-09-19",
                  "request_hash": "sha256:7eac1cd1fd4cd5268c1b873571b4a3212a532ca60f4a788d084239f962a2dd61",
                  "data_versions": {
                    "denylist": "2026-08-03.1",
                    "sinks": "2026-09-19",
                    "bytecode_shapes": "2026-09-19",
                    "policy": "2026-09-19",
                    "chain": "eip155:8453"
                  },
                  "warnings": [
                    "No Base RPC endpoint is configured, so this answer covers only what twenty bytes can tell you: checksum integrity, distance from the address you expected, and known sinks. Every chain-dependent field is reported as unknown rather than assumed."
                  ]
                }
              }
            }
          },
          "400": {
            "description": "INPUT_INVALID",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false,
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {}
                      }
                    }
                  }
                }
              }
            }
          },
          "402": {
            "description": "Payment required. Body carries the x402 challenge; see PAYMENT-REQUIRED header.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false,
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {}
                      }
                    }
                  }
                }
              }
            }
          },
          "422": {
            "description": "UNSUPPORTED or INDETERMINATE. Not charged.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false,
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {}
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "RATE_LIMITED",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false,
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {}
                      }
                    }
                  }
                }
              }
            }
          },
          "502": {
            "description": "Upstream or facilitator unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false,
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {}
                      }
                    }
                  }
                }
              }
            }
          },
          "504": {
            "description": "UPSTREAM_TIMEOUT",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false,
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {}
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "additionalProperties": false,
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              },
              "details": {}
            }
          }
        }
      }
    }
  }
}