{
  "openapi": "3.1.0",
  "info": {
    "title": "Kanmani",
    "version": "1.0.0",
    "summary": "Build, register and verify ERC-8004 agents on Monad.",
    "description": "Free checks for building an ERC-8004 agent (registration and evidence), plus the verdicts Kanmani records about every agent on Monad. No key is ever taken: registration returns calldata the agent signs itself. `unknown` means undecided and must not be treated as `false`.",
    "contact": {
      "url": "https://kanmani.xyz/developers"
    },
    "license": {
      "name": "MIT",
      "identifier": "MIT"
    }
  },
  "servers": [
    {
      "url": "https://kanmani.xyz"
    }
  ],
  "security": [],
  "externalDocs": {
    "description": "Build guide (also an agentskills.io SKILL.md)",
    "url": "https://kanmani.xyz/skill.md"
  },
  "tags": [
    {
      "name": "build",
      "description": "Free checks for building an agent"
    },
    {
      "name": "read",
      "description": "What Kanmani has measured"
    },
    {
      "name": "paid",
      "description": "x402-priced work"
    }
  ],
  "paths": {
    "/api/registration/check": {
      "post": {
        "operationId": "check_registration",
        "tags": [
          "build"
        ],
        "summary": "Check an agent registration and get the exact transaction to send",
        "description": "Validates the draft, returns problems, consequences, the committed document and agentURI plus calldata for register(string) on the identity registry 0x8004A169FB4a3325136EB29fA0ceB6D2e539a432 (chain 143). setAgentURI(uint256,string) instead when agentId is given. With sender it also checks that address can pay gas. The agent's own key must send the transaction: the sender becomes the owner.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RegistrationInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The report. Read data.ready first.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "version": {
                      "type": "integer"
                    },
                    "chain": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "integer"
                        },
                        "name": {
                          "type": "string"
                        }
                      }
                    },
                    "checkedAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "checkedAtBlock": {
                      "type": [
                        "integer",
                        "null"
                      ]
                    },
                    "reproduce": {
                      "type": "string",
                      "description": "The command that re-derives this answer."
                    },
                    "data": {
                      "$ref": "#/components/schemas/RegistrationReport"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The draft could not be read. detail says which field.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/evidence/check": {
      "post": {
        "operationId": "check_evidence",
        "tags": [
          "build"
        ],
        "summary": "Check an evidence document before publishing it",
        "description": "Judges the document with the same verifier as every published verdict. A false is searched for on other chains so a wrong network field is named. Send the document itself; URLs are refused, never fetched.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "document"
                ],
                "properties": {
                  "document": {
                    "oneOf": [
                      {
                        "type": "object"
                      },
                      {
                        "type": "string",
                        "description": "JSON text or a data: URI"
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The outcome the document will get.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "version": {
                      "type": "integer"
                    },
                    "chain": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "integer"
                        },
                        "name": {
                          "type": "string"
                        }
                      }
                    },
                    "checkedAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "checkedAtBlock": {
                      "type": [
                        "integer",
                        "null"
                      ]
                    },
                    "reproduce": {
                      "type": "string",
                      "description": "The command that re-derives this answer."
                    },
                    "data": {
                      "$ref": "#/components/schemas/EvidenceReport"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "No document or a URL was sent.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "The check could not complete. Retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/agent/{id}": {
      "get": {
        "operationId": "get_agent",
        "tags": [
          "read"
        ],
        "summary": "What Kanmani measures about one agent",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^\\d+$"
            },
            "description": "ERC-8004 agent id on Monad"
          }
        ],
        "responses": {
          "200": {
            "description": "One agent. Unknown fields are null, never zero.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "version": {
                      "type": "integer"
                    },
                    "chain": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "integer"
                        },
                        "name": {
                          "type": "string"
                        }
                      }
                    },
                    "checkedAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "checkedAtBlock": {
                      "type": [
                        "integer",
                        "null"
                      ]
                    },
                    "reproduce": {
                      "type": "string",
                      "description": "The command that re-derives this answer."
                    },
                    "data": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not in this index.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/account/{address}": {
      "get": {
        "operationId": "get_account",
        "tags": [
          "read"
        ],
        "summary": "Agents an address owns, with bond state and balances",
        "parameters": [
          {
            "name": "address",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^0x[0-9a-fA-F]{40}$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Balances are null when unreadable, never 0.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "version": {
                      "type": "integer"
                    },
                    "chain": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "integer"
                        },
                        "name": {
                          "type": "string"
                        }
                      }
                    },
                    "checkedAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "checkedAtBlock": {
                      "type": [
                        "integer",
                        "null"
                      ]
                    },
                    "reproduce": {
                      "type": "string",
                      "description": "The command that re-derives this answer."
                    },
                    "data": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Not an address.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/claims": {
      "get": {
        "operationId": "list_claims",
        "tags": [
          "read"
        ],
        "summary": "Checked payment claims, filterable",
        "parameters": [
          {
            "name": "outcome",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "true",
                "false",
                "noClaim",
                "unknown"
              ]
            }
          },
          {
            "name": "rung",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "declared",
                "resolvable",
                "intact",
                "parsed",
                "true"
              ]
            }
          },
          {
            "name": "agent",
            "in": "query",
            "schema": {
              "type": "string",
              "pattern": "^\\d+$"
            }
          },
          {
            "name": "network",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "mapping",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 500
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of claims.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "version": {
                      "type": "integer"
                    },
                    "chain": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "integer"
                        },
                        "name": {
                          "type": "string"
                        }
                      }
                    },
                    "checkedAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "checkedAtBlock": {
                      "type": [
                        "integer",
                        "null"
                      ]
                    },
                    "reproduce": {
                      "type": "string",
                      "description": "The command that re-derives this answer."
                    },
                    "data": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad filter.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/sla/{agentId}": {
      "get": {
        "operationId": "get_claim_truth_rate",
        "tags": [
          "read"
        ],
        "summary": "An agent's claim-truth rate over a block window",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^\\d+$"
            }
          },
          {
            "name": "fromBlock",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "toBlock",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "publishers",
            "in": "query",
            "description": "Optional scope. Comma list of up to 8 wallets. Only feedback published by one of them is sampled. Absent means every publisher.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "recipient",
            "in": "query",
            "description": "Optional scope. A 20-byte address or \"agent\". Only claims whose payment was claimed to reach that address (or the agent's own owner or wallet) are sampled. Absent means any recipient.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The rate and its sample.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "version": {
                      "type": "integer"
                    },
                    "chain": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "integer"
                        },
                        "name": {
                          "type": "string"
                        }
                      }
                    },
                    "checkedAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "checkedAtBlock": {
                      "type": [
                        "integer",
                        "null"
                      ]
                    },
                    "reproduce": {
                      "type": "string",
                      "description": "The command that re-derives this answer."
                    },
                    "data": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/verify": {
      "post": {
        "operationId": "verify_hosted_document",
        "tags": [
          "paid"
        ],
        "summary": "Check a hosted evidence document (x402, 0.01 USDC)",
        "description": "Answers 402 with an x402 challenge. Pay it (exact, USDC on chain 143) and resend with PAYMENT-SIGNATURE.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "uri": {
                    "type": "string"
                  },
                  "id": {
                    "type": "string"
                  },
                  "feedbackHash": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Verdict.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "version": {
                      "type": "integer"
                    },
                    "chain": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "integer"
                        },
                        "name": {
                          "type": "string"
                        }
                      }
                    },
                    "checkedAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "checkedAtBlock": {
                      "type": [
                        "integer",
                        "null"
                      ]
                    },
                    "reproduce": {
                      "type": "string",
                      "description": "The command that re-derives this answer."
                    },
                    "data": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "402": {
            "description": "x402 payment required. The body is the challenge."
          }
        }
      }
    },
    "/api/service/{slug}": {
      "get": {
        "operationId": "get_agent_service",
        "tags": [
          "paid"
        ],
        "summary": "Kanmani's twelve agents: price, meter and how to pay (see /hire)",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "sentinel",
                "assay",
                "locator",
                "notary",
                "registrar",
                "ledger",
                "twin",
                "pulse",
                "doctor",
                "linter",
                "bondsman",
                "scribe"
              ]
            }
          }
        ],
        "responses": {
          "402": {
            "description": "The price (upto ceiling or exact) and the reason. Free to read."
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Problem": {
        "type": "object",
        "description": "RFC 9457 problem details",
        "properties": {
          "type": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "detail": {
            "type": "string"
          }
        }
      },
      "RegistrationInput": {
        "type": "object",
        "required": [
          "draft"
        ],
        "properties": {
          "draft": {
            "type": "object",
            "required": [
              "name"
            ],
            "properties": {
              "name": {
                "type": "string"
              },
              "description": {
                "type": "string"
              },
              "url": {
                "type": "string",
                "description": "the operator's site"
              },
              "skills": {
                "type": "array",
                "maxItems": 32,
                "items": {
                  "type": "object",
                  "required": [
                    "id",
                    "endpoint"
                  ],
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "endpoint": {
                      "type": "string"
                    },
                    "x402": {
                      "type": "boolean"
                    }
                  }
                }
              },
              "refuses": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "what this agent will not do"
              }
            }
          },
          "kind": {
            "type": "string",
            "enum": [
              "data",
              "https"
            ],
            "default": "data",
            "description": "data puts the document on chain so it cannot go dead"
          },
          "hostedAt": {
            "type": "string",
            "description": "only for kind https"
          },
          "chainId": {
            "type": "integer",
            "enum": [
              143
            ],
            "default": 143
          },
          "agentId": {
            "type": "string",
            "pattern": "^\\d+$",
            "description": "only when repointing an agent the sender owns"
          },
          "sender": {
            "type": "string",
            "pattern": "^0x[0-9a-fA-F]{40}$",
            "description": "checks this address can pay the gas"
          }
        }
      },
      "RegistrationReport": {
        "type": "object",
        "properties": {
          "ready": {
            "type": "boolean"
          },
          "problems": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "consequences": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "label": {
                  "type": "string"
                },
                "met": {
                  "type": "boolean"
                },
                "why": {
                  "type": "string"
                }
              }
            }
          },
          "document": {
            "type": "object"
          },
          "agentURI": {
            "type": "string"
          },
          "uriBytes": {
            "type": "integer"
          },
          "transaction": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "chainId": {
                "type": "integer"
              },
              "to": {
                "type": "string"
              },
              "function": {
                "type": "string"
              },
              "data": {
                "type": "string"
              },
              "value": {
                "type": "string"
              }
            }
          },
          "send": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "cast": {
                "type": "string"
              },
              "viem": {
                "type": "string"
              }
            }
          },
          "gas": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "state": {
                "type": "string",
                "enum": [
                  "enough",
                  "short",
                  "unknown"
                ]
              },
              "have": {
                "type": "string"
              },
              "need": {
                "type": "string"
              },
              "short": {
                "type": "string"
              },
              "fix": {
                "type": "string"
              }
            }
          },
          "canSend": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "ready AND the sender can pay gas. null when no sender was given or gas could not be read."
          },
          "next": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "EvidenceReport": {
        "type": "object",
        "properties": {
          "outcome": {
            "type": "string",
            "enum": [
              "true",
              "false",
              "noClaim",
              "unknown"
            ]
          },
          "rung": {
            "type": "string"
          },
          "reason": {
            "type": "string"
          },
          "declaredNetwork": {
            "type": [
              "string",
              "null"
            ]
          },
          "declaredTx": {
            "type": [
              "string",
              "null"
            ]
          },
          "mapping": {
            "type": [
              "string",
              "null"
            ]
          },
          "foundOnChain": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "chain": {
                "type": "string"
              },
              "chainId": {
                "type": "integer"
              },
              "block": {
                "type": "integer"
              }
            }
          },
          "advice": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      }
    }
  }
}