{
 "openapi": "3.1.0",
 "info": {
  "title": "reverser.space session API",
  "version": "1.1.0",
  "description": "Read-only JSON API behind reverser.space share links. Every share URL app.reverser.space/v/{token} exposes this API at /api/v/{token}/. The token is the whole capability: no account, no header, no cookie.\n\nAddresses: parameters take 0x-prefixed hex strings like 0x401000. Responses return addresses as decimal byte offsets (Ghidra offsets); the one exception is /triage, which returns 0x-prefixed hex strings ready to pass back.\n\nErrors are always {\"error\": \"...\"}. A session idle long enough reopens from its saved Ghidra project on the first request, which can take a few seconds. Poll /ready to wait deliberately.\n\nStatus codes: 400 malformed parameter; 403 disabled by the gateway; 404 invalid or revoked token, or nothing at that address; 409 uploaded but not analysed yet; 503 at capacity, retry later.\n\nA WebSocket at /api/v/{token}/ws streams live session events (renames, comments, presence); it is outside this spec. Accounts get a read-write API as well: see /openapi-account.json."
 },
 "externalDocs": {
  "description": "Guide with worked examples",
  "url": "https://app.reverser.space/agent-api.html"
 },
 "servers": [
  {
   "url": "https://app.reverser.space"
  }
 ],
 "security": [],
 "paths": {
  "/api/v/{token}/info": {
   "get": {
    "operationId": "info",
    "summary": "File format, architecture, entry point and hardening flags",
    "parameters": [
     {
      "$ref": "#/components/parameters/token"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Info"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    }
   }
  },
  "/api/v/{token}/overview": {
   "get": {
    "operationId": "overview",
    "summary": "Summary counts: functions, strings, symbols, imports, xrefs, calls",
    "parameters": [
     {
      "$ref": "#/components/parameters/token"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Overview"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    }
   }
  },
  "/api/v/{token}/triage": {
   "get": {
    "operationId": "triage",
    "summary": "Functions ranked by how likely they are to repay reading first, with reasons",
    "parameters": [
     {
      "$ref": "#/components/parameters/token"
     },
     {
      "name": "limit",
      "in": "query",
      "description": "How many ranked functions to return (default 100)",
      "schema": {
       "type": "integer",
       "minimum": 1,
       "maximum": 500,
       "default": 100
      }
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Triage"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    }
   }
  },
  "/api/v/{token}/hashes": {
   "get": {
    "operationId": "hashes",
    "summary": "File hashes and whole-file entropy",
    "parameters": [
     {
      "$ref": "#/components/parameters/token"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Hashes"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    }
   }
  },
  "/api/v/{token}/entropy": {
   "get": {
    "operationId": "entropy",
    "summary": "Shannon entropy per bucket across initialised memory, labelled by section",
    "description": "High and flat reads as compressed or encrypted; low and spiky as text or padding. Buckets never straddle sections, so the answer can hold a few more samples than asked for.",
    "parameters": [
     {
      "$ref": "#/components/parameters/token"
     },
     {
      "name": "buckets",
      "in": "query",
      "description": "Target resolution (default 256)",
      "schema": {
       "type": "integer",
       "minimum": 16,
       "maximum": 2048,
       "default": 256
      }
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/EntropyBucket"
         }
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    }
   }
  },
  "/api/v/{token}/sections": {
   "get": {
    "operationId": "sections",
    "summary": "Sections with addresses, sizes and permissions",
    "parameters": [
     {
      "$ref": "#/components/parameters/token"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/Section"
         }
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    }
   }
  },
  "/api/v/{token}/certificates": {
   "get": {
    "operationId": "certificates",
    "summary": "Code-signing certificates where the format carries them",
    "parameters": [
     {
      "$ref": "#/components/parameters/token"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "additionalProperties": true
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    }
   }
  },
  "/api/v/{token}/versioninfo": {
   "get": {
    "operationId": "versioninfo",
    "summary": "Imported library version requirements",
    "parameters": [
     {
      "$ref": "#/components/parameters/token"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "description": "Format-specific; a list of libraries with their version tags on ELF",
         "type": [
          "array",
          "object"
         ],
         "items": {
          "type": "object",
          "additionalProperties": true
         },
         "additionalProperties": true
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    }
   }
  },
  "/api/v/{token}/libraries": {
   "get": {
    "operationId": "libraries",
    "summary": "Shared libraries the binary links against",
    "parameters": [
     {
      "$ref": "#/components/parameters/token"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "type": "string"
         }
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    }
   }
  },
  "/api/v/{token}/functions": {
   "get": {
    "operationId": "functions",
    "summary": "Every function with name, address, size and complexity",
    "parameters": [
     {
      "$ref": "#/components/parameters/token"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/Function"
         }
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    }
   }
  },
  "/api/v/{token}/disasm": {
   "get": {
    "operationId": "disasm",
    "summary": "Disassembly of the function at an address",
    "parameters": [
     {
      "$ref": "#/components/parameters/token"
     },
     {
      "$ref": "#/components/parameters/addr"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Disasm"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/badRequest"
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    }
   }
  },
  "/api/v/{token}/decompile": {
   "get": {
    "operationId": "decompile",
    "summary": "Decompiled C for the function at an address",
    "parameters": [
     {
      "$ref": "#/components/parameters/token"
     },
     {
      "$ref": "#/components/parameters/addr"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Decompile"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/badRequest"
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    }
   }
  },
  "/api/v/{token}/vars": {
   "get": {
    "operationId": "vars",
    "summary": "The function's variables and arguments with types and storage",
    "parameters": [
     {
      "$ref": "#/components/parameters/token"
     },
     {
      "$ref": "#/components/parameters/addr"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Vars"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/badRequest"
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    }
   }
  },
  "/api/v/{token}/graph": {
   "get": {
    "operationId": "graph",
    "summary": "Basic-block control-flow graph of the function at an address",
    "parameters": [
     {
      "$ref": "#/components/parameters/token"
     },
     {
      "$ref": "#/components/parameters/addr"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/Graph"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/badRequest"
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    }
   }
  },
  "/api/v/{token}/xrefs": {
   "get": {
    "operationId": "xrefs",
    "summary": "Cross-references to an address: who reads, writes, calls or jumps here",
    "parameters": [
     {
      "$ref": "#/components/parameters/token"
     },
     {
      "$ref": "#/components/parameters/addr"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/Xref"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/badRequest"
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    }
   }
  },
  "/api/v/{token}/calltree": {
   "get": {
    "operationId": "calltree",
    "summary": "Callers and callees of the function at an address",
    "parameters": [
     {
      "$ref": "#/components/parameters/token"
     },
     {
      "$ref": "#/components/parameters/addr"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/CallTree"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/badRequest"
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    }
   }
  },
  "/api/v/{token}/callgraph": {
   "get": {
    "operationId": "callgraph",
    "summary": "The whole-program call graph: every function with its callees by name",
    "parameters": [
     {
      "$ref": "#/components/parameters/token"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/CallGraphNode"
         }
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    }
   }
  },
  "/api/v/{token}/instruction": {
   "get": {
    "operationId": "instruction",
    "summary": "One instruction decoded: operands, control flow, p-code",
    "parameters": [
     {
      "$ref": "#/components/parameters/token"
     },
     {
      "$ref": "#/components/parameters/addr"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Instruction"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/badRequest"
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    }
   }
  },
  "/api/v/{token}/resolveaddr": {
   "get": {
    "operationId": "resolveaddr",
    "summary": "The function containing an address",
    "parameters": [
     {
      "$ref": "#/components/parameters/token"
     },
     {
      "$ref": "#/components/parameters/addr"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ResolveAddr"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/badRequest"
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    }
   }
  },
  "/api/v/{token}/signature": {
   "get": {
    "operationId": "signature",
    "summary": "The function's C prototype and calling convention",
    "parameters": [
     {
      "$ref": "#/components/parameters/token"
     },
     {
      "$ref": "#/components/parameters/addr"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Signature"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/badRequest"
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    }
   }
  },
  "/api/v/{token}/strings": {
   "get": {
    "operationId": "strings",
    "summary": "Strings with addresses and sections",
    "parameters": [
     {
      "$ref": "#/components/parameters/token"
     },
     {
      "name": "scope",
      "in": "query",
      "description": "Pass 'all' to additionally sweep undefined memory for string-shaped runs; noisier, but finds strings compilers park in .text",
      "schema": {
       "type": "string",
       "enum": [
        "all"
       ]
      }
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/StringItem"
         }
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    }
   }
  },
  "/api/v/{token}/hex": {
   "get": {
    "operationId": "hex",
    "summary": "Raw bytes at an address, as an array of byte values",
    "parameters": [
     {
      "$ref": "#/components/parameters/token"
     },
     {
      "$ref": "#/components/parameters/addr"
     },
     {
      "name": "len",
      "in": "query",
      "description": "How many bytes (default 256)",
      "schema": {
       "type": "integer",
       "minimum": 1,
       "maximum": 4096,
       "default": 256
      }
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "type": "integer",
          "minimum": 0,
          "maximum": 255
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/badRequest"
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    }
   }
  },
  "/api/v/{token}/symbols": {
   "get": {
    "operationId": "symbols",
    "summary": "Every symbol with address, binding and type",
    "parameters": [
     {
      "$ref": "#/components/parameters/token"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/Symbol"
         }
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    }
   }
  },
  "/api/v/{token}/imports": {
   "get": {
    "operationId": "imports",
    "summary": "Imported functions with their thunk addresses",
    "parameters": [
     {
      "$ref": "#/components/parameters/token"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/Import"
         }
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    }
   }
  },
  "/api/v/{token}/exports": {
   "get": {
    "operationId": "exports",
    "summary": "Exported symbols",
    "parameters": [
     {
      "$ref": "#/components/parameters/token"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/Symbol"
         }
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    }
   }
  },
  "/api/v/{token}/types": {
   "get": {
    "operationId": "types",
    "summary": "Data types known to the program",
    "parameters": [
     {
      "$ref": "#/components/parameters/token"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Types"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    }
   }
  },
  "/api/v/{token}/type": {
   "get": {
    "operationId": "type",
    "summary": "One type's definition: members for a composite, values for an enum",
    "parameters": [
     {
      "$ref": "#/components/parameters/token"
     },
     {
      "name": "name",
      "in": "query",
      "required": true,
      "description": "Type name or category path, e.g. \"sockaddr_in\"",
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/TypeDetail"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    }
   }
  },
  "/api/v/{token}/type/uses": {
   "get": {
    "operationId": "typeUses",
    "summary": "How many data, variables and types would revert to undefined if this type were deleted",
    "parameters": [
     {
      "$ref": "#/components/parameters/token"
     },
     {
      "name": "name",
      "in": "query",
      "required": true,
      "description": "Type name or category path, e.g. \"sockaddr_in\"",
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/TypeUses"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    }
   }
  },
  "/api/v/{token}/search": {
   "get": {
    "operationId": "search",
    "summary": "Search strings, symbols and bytes across the program",
    "parameters": [
     {
      "$ref": "#/components/parameters/token"
     },
     {
      "name": "query",
      "in": "query",
      "description": "What to search for. Literal text by default; hex bytes like 'deadbeef' with mode=hex; a Java regular expression with mode=regex",
      "schema": {
       "type": "string"
      },
      "required": true
     },
     {
      "name": "mode",
      "in": "query",
      "description": "How to interpret the query. Anything else falls back to a literal text search",
      "schema": {
       "type": "string",
       "enum": [
        "hex",
        "regex"
       ]
      }
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/SearchHit"
         }
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    }
   }
  },
  "/api/v/{token}/comments": {
   "get": {
    "operationId": "comments",
    "summary": "Analyst comments with author and address",
    "parameters": [
     {
      "$ref": "#/components/parameters/token"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/Comment"
         }
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    }
   }
  },
  "/api/v/{token}/labels": {
   "get": {
    "operationId": "labels",
    "summary": "User and analysis labels at an address",
    "parameters": [
     {
      "$ref": "#/components/parameters/token"
     },
     {
      "$ref": "#/components/parameters/addr"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/Label"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/badRequest"
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    }
   }
  },
  "/api/v/{token}/bookmarks": {
   "get": {
    "operationId": "bookmarks",
    "summary": "Bookmarked addresses with notes",
    "parameters": [
     {
      "$ref": "#/components/parameters/token"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/Bookmark"
         }
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    }
   }
  },
  "/api/v/{token}/notes": {
   "get": {
    "operationId": "notes",
    "summary": "The analysts' shared write-up of this binary",
    "description": "Markdown, maintained by the people and agents working the session. Usually the best first read: it says what the binary is and where the interesting parts are.",
    "parameters": [
     {
      "$ref": "#/components/parameters/token"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Notes"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    }
   }
  },
  "/api/v/{token}/findings": {
   "get": {
    "operationId": "listFindings",
    "summary": "The structured findings background agent runs recorded, oldest first, superseded ones marked",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "The share token."
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/Finding"
         }
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    }
   }
  },
  "/api/v/{token}/undostate": {
   "get": {
    "operationId": "undostate",
    "summary": "What undo would revert next, and the program's history stack",
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "additionalProperties": false,
         "properties": {
          "canUndo": {
           "type": "boolean"
          },
          "canRedo": {
           "type": "boolean"
          },
          "undoName": {
           "type": "string",
           "description": "The next change undo would revert, named with who made it"
          },
          "redoName": {
           "type": "string"
          },
          "undoStack": {
           "type": "array",
           "items": {
            "type": "string"
           },
           "description": "Newest first"
          },
          "redoStack": {
           "type": "array",
           "items": {
            "type": "string"
           }
          }
         }
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    },
    "parameters": [
     {
      "$ref": "#/components/parameters/token"
     }
    ]
   }
  },
  "/api/v/{token}/activity": {
   "get": {
    "operationId": "activity",
    "summary": "Recent session activity: renames, comments, notes edits",
    "parameters": [
     {
      "$ref": "#/components/parameters/token"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/ActivityEvent"
         }
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    }
   }
  },
  "/api/v/{token}/ready": {
   "get": {
    "operationId": "ready",
    "summary": "Whether the session is open and answering",
    "description": "The first request after a session has been idle blocks for a few seconds while it reopens from its saved Ghidra project. Poll this to wait deliberately instead.",
    "parameters": [
     {
      "$ref": "#/components/parameters/token"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Ready"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    }
   }
  },
  "/api/v/{token}/session": {
   "get": {
    "operationId": "session",
    "summary": "What this share link points at: binary name, status, whether download is allowed",
    "description": "Answered without waking the session, so it is always fast and never counts as activity.",
    "parameters": [
     {
      "$ref": "#/components/parameters/token"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ViewerSession"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    }
   }
  },
  "/api/v/{token}/chat": {
   "get": {
    "operationId": "chat",
    "summary": "The session's shared chat, humans and agents alike",
    "parameters": [
     {
      "$ref": "#/components/parameters/token"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/ChatMessage"
         }
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    }
   }
  },
  "/api/v/{token}/layout": {
   "get": {
    "operationId": "layout",
    "summary": "The creator's saved panel layout for the workspace UI",
    "parameters": [
     {
      "$ref": "#/components/parameters/token"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Layout"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    }
   }
  },
  "/api/v/{token}/download": {
   "get": {
    "operationId": "download",
    "summary": "The original uploaded binary, when the gateway allows it",
    "parameters": [
     {
      "$ref": "#/components/parameters/token"
     }
    ],
    "responses": {
     "200": {
      "description": "The binary itself",
      "content": {
       "application/octet-stream": {
        "schema": {
         "type": "string",
         "format": "binary"
        }
       }
      }
     },
     "403": {
      "description": "Downloads are disabled for share links on this gateway",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    }
   }
  },
  "/api/p/{author}/{slug}": {
   "get": {
    "operationId": "getPublicPost",
    "summary": "A published writeup: its prose, and the token reaching the frozen session it argues about",
    "parameters": [
     {
      "name": "author",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "The author's username, matched case-insensitively. Slugs are unique per author, so this segment is part of the post's name."
     },
     {
      "name": "slug",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "The writeup's published slug."
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/PublicPost"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    }
   }
  }
 },
 "components": {
  "parameters": {
   "token": {
    "name": "token",
    "in": "path",
    "required": true,
    "description": "The share token from a session link (app.reverser.space/v/{token})",
    "schema": {
     "type": "string",
     "pattern": "^[A-Za-z0-9]{16,128}$"
    }
   },
   "addr": {
    "name": "addr",
    "in": "query",
    "required": true,
    "description": "Address as a 0x-prefixed hex string, e.g. 0x401000. Function endpoints accept any address inside the function.",
    "schema": {
     "type": "string",
     "pattern": "^(0x)?[0-9a-fA-F]+$"
    }
   }
  },
  "responses": {
   "badRequest": {
    "description": "Malformed parameter or body (bad address, out-of-range number)",
    "content": {
     "application/json": {
      "schema": {
       "$ref": "#/components/schemas/Error"
      }
     }
    }
   },
   "notFound": {
    "description": "Nothing there: unknown session or token, or nothing at that address",
    "content": {
     "application/json": {
      "schema": {
       "$ref": "#/components/schemas/Error"
      }
     }
    }
   },
   "error": {
    "description": "Any other failure, same {error} shape. 409: uploaded but not analysed yet. 503: the gateway is at capacity or the session's worker is unavailable; retry later.",
    "content": {
     "application/json": {
      "schema": {
       "$ref": "#/components/schemas/Error"
      }
     }
    }
   }
  },
  "schemas": {
   "Error": {
    "type": "object",
    "properties": {
     "error": {
      "type": "string",
      "description": "What went wrong, as a sentence"
     }
    },
    "additionalProperties": false,
    "required": [
     "error"
    ]
   },
   "Info": {
    "type": "object",
    "properties": {
     "core": {
      "type": "object",
      "properties": {
       "file": {
        "type": "string",
        "description": "Display name"
       },
       "format": {
        "type": "string",
        "description": "Container format, e.g. ELF or PE"
       },
       "humansz": {
        "type": "string",
        "description": "Human-readable size"
       },
       "size": {
        "type": "integer",
        "description": "Size in bytes"
       }
      },
      "additionalProperties": true
     },
     "bin": {
      "type": "object",
      "properties": {
       "arch": {
        "type": "string"
       },
       "bits": {
        "type": "integer"
       },
       "endian": {
        "type": "string",
        "enum": [
         "little",
         "big"
        ]
       },
       "baddr": {
        "type": "integer",
        "description": "Image base address"
       },
       "bintype": {
        "type": "string"
       },
       "compiler": {
        "type": "string"
       },
       "language": {
        "type": "string",
        "description": "Ghidra language id, e.g. x86:LE:64:default"
       },
       "canary": {
        "type": "boolean"
       },
       "nx": {
        "type": "boolean"
       },
       "pic": {
        "type": "boolean"
       },
       "relocs": {
        "type": "boolean"
       },
       "relro": {
        "type": "string"
       },
       "static": {
        "type": "boolean"
       },
       "stripped": {
        "type": "boolean"
       }
      },
      "additionalProperties": true
     }
    },
    "additionalProperties": false,
    "required": [
     "core",
     "bin"
    ]
   },
   "Overview": {
    "type": "object",
    "properties": {
     "functions": {
      "type": "integer"
     },
     "xrefs": {
      "type": "integer"
     },
     "calls": {
      "type": "integer"
     },
     "strings": {
      "type": "integer"
     },
     "symbols": {
      "type": "integer"
     },
     "imports": {
      "type": "integer"
     }
    },
    "additionalProperties": false
   },
   "Triage": {
    "type": "object",
    "properties": {
     "items": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "addr": {
         "type": "string",
         "description": "Function entry point as a 0x-prefixed hex string (unlike list endpoints, which return decimal offsets)"
        },
        "name": {
         "type": "string"
        },
        "size": {
         "type": "integer",
         "description": "Function size in bytes"
        },
        "score": {
         "type": "integer",
         "description": "Rank score; higher means more worth reading first"
        },
        "reasons": {
         "type": "array",
         "items": {
          "type": "string"
         },
         "description": "Why it ranked, e.g. 'exported entry point', 'complex'"
        }
       },
       "additionalProperties": false
      }
     },
     "ranked": {
      "type": "integer",
      "description": "How many functions scored above zero"
     },
     "total": {
      "type": "integer",
      "description": "How many functions exist"
     }
    },
    "additionalProperties": false,
    "required": [
     "items",
     "ranked",
     "total"
    ]
   },
   "Hashes": {
    "type": "object",
    "properties": {
     "md5": {
      "type": "string"
     },
     "sha1": {
      "type": "string"
     },
     "sha256": {
      "type": "string"
     },
     "crc32": {
      "type": "string"
     },
     "entropy": {
      "type": "string",
      "description": "Whole-file Shannon entropy, 0-8 bits per byte"
     }
    },
    "additionalProperties": false
   },
   "EntropyBucket": {
    "type": "object",
    "properties": {
     "addr": {
      "type": "integer",
      "description": "Address as a decimal byte offset in the program's address space. Render as hex for display; pass back to addr parameters as a 0x-prefixed hex string."
     },
     "size": {
      "type": "integer",
      "description": "Bytes sampled in this bucket"
     },
     "section": {
      "type": "string",
      "description": "Memory block the bucket lies in; buckets never straddle blocks"
     },
     "entropy": {
      "type": "number",
      "description": "Shannon entropy of the bucket, 0-8 bits per byte"
     }
    },
    "additionalProperties": false
   },
   "Section": {
    "type": "object",
    "properties": {
     "name": {
      "type": "string"
     },
     "size": {
      "type": "integer",
      "description": "File size"
     },
     "vsize": {
      "type": "integer",
      "description": "Size in memory"
     },
     "type": {
      "type": "string"
     },
     "perm": {
      "type": "string",
      "description": "Permissions as rwx string, e.g. 'r-x'"
     },
     "flags": {
      "type": "integer"
     },
     "vaddr": {
      "type": "integer",
      "description": "Address as a decimal byte offset in the program's address space. Render as hex for display; pass back to addr parameters as a 0x-prefixed hex string."
     },
     "paddr": {
      "type": "integer",
      "description": "File offset"
     },
     "loaded": {
      "type": "boolean"
     }
    },
    "additionalProperties": false
   },
   "Function": {
    "type": "object",
    "properties": {
     "addr": {
      "type": "integer",
      "description": "Address as a decimal byte offset in the program's address space. Render as hex for display; pass back to addr parameters as a 0x-prefixed hex string."
     },
     "name": {
      "type": "string"
     },
     "size": {
      "type": "integer",
      "description": "Bytes in the function body"
     },
     "end": {
      "type": "integer",
      "description": "Last address, decimal"
     },
     "nbbs": {
      "type": "integer",
      "description": "Basic block count"
     },
     "cc": {
      "type": "integer",
      "description": "Cyclomatic complexity"
     },
     "ninstrs": {
      "type": "integer",
      "description": "Instruction count"
     },
     "indegree": {
      "type": "integer",
      "description": "How many functions call this one"
     }
    },
    "additionalProperties": false
   },
   "Op": {
    "type": "object",
    "properties": {
     "addr": {
      "type": "integer",
      "description": "Address as a decimal byte offset in the program's address space. Render as hex for display; pass back to addr parameters as a 0x-prefixed hex string."
     },
     "bytes": {
      "type": "string",
      "description": "Instruction bytes as lowercase hex"
     },
     "disasm": {
      "type": "string"
     },
     "opcode": {
      "type": "string"
     }
    },
    "additionalProperties": false
   },
   "Disasm": {
    "type": "object",
    "properties": {
     "addr": {
      "type": "integer",
      "description": "Address as a decimal byte offset in the program's address space. Render as hex for display; pass back to addr parameters as a 0x-prefixed hex string."
     },
     "name": {
      "type": "string",
      "description": "Containing function"
     },
     "size": {
      "type": "integer"
     },
     "ops": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/Op"
      }
     }
    },
    "additionalProperties": false
   },
   "Decompile": {
    "type": "object",
    "properties": {
     "lines": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "str": {
         "type": "string",
         "description": "One line of C"
        },
        "offset": {
         "type": "integer",
         "description": "Address the line maps to, decimal; absent on lines with no location"
        }
       },
       "additionalProperties": false,
       "required": [
        "str"
       ]
      }
     },
     "annotatedVars": {
      "type": "array",
      "items": {
       "type": "string"
      },
      "description": "Variable and symbol names appearing in the listing"
     }
    },
    "additionalProperties": false,
    "required": [
     "lines"
    ]
   },
   "Vars": {
    "type": "object",
    "properties": {
     "reg": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/Var"
      },
      "description": "Register-backed variables"
     },
     "sp": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/Var"
      },
      "description": "Stack variables"
     },
     "bp": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/Var"
      },
      "description": "Frame-base variables"
     }
    },
    "additionalProperties": false
   },
   "Var": {
    "type": "object",
    "properties": {
     "name": {
      "type": "string"
     },
     "type": {
      "type": "string"
     },
     "kind": {
      "type": "string",
      "enum": [
       "arg",
       "var"
      ]
     },
     "ref": {
      "type": "string",
      "description": "Storage location, e.g. 'RDI:8' or a stack offset"
     }
    },
    "additionalProperties": false
   },
   "Graph": {
    "type": "object",
    "properties": {
     "name": {
      "type": "string",
      "description": "Function name"
     },
     "addr": {
      "type": "integer",
      "description": "Address as a decimal byte offset in the program's address space. Render as hex for display; pass back to addr parameters as a 0x-prefixed hex string."
     },
     "blocks": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "addr": {
         "type": "integer",
         "description": "Address as a decimal byte offset in the program's address space. Render as hex for display; pass back to addr parameters as a 0x-prefixed hex string."
        },
        "size": {
         "type": "integer",
         "description": "Addresses spanned"
        },
        "jump": {
         "type": "integer",
         "description": "Branch-taken successor, decimal; absent when none"
        },
        "fail": {
         "type": "integer",
         "description": "Fall-through successor, decimal; absent when none"
        },
        "ops": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/Op"
         }
        }
       },
       "additionalProperties": false,
       "required": [
        "addr",
        "size",
        "ops"
       ]
      }
     }
    },
    "additionalProperties": false
   },
   "Xref": {
    "type": "object",
    "properties": {
     "from": {
      "type": "integer",
      "description": "Referencing address, decimal"
     },
     "type": {
      "type": "string",
      "description": "Reference type, e.g. CALL, READ, WRITE, JUMP"
     },
     "opcode": {
      "type": "string",
      "description": "Disassembly at the referencing address"
     },
     "fcn_name": {
      "type": "string",
      "description": "Function containing the reference, when any"
     },
     "realname": {
      "type": "string"
     }
    },
    "additionalProperties": false
   },
   "CallTree": {
    "type": "object",
    "properties": {
     "incoming": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/NamedAddr"
      },
      "description": "Functions that call this one"
     },
     "outgoing": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/NamedAddr"
      },
      "description": "Functions this one calls"
     }
    },
    "additionalProperties": false
   },
   "CallGraphNode": {
    "type": "object",
    "properties": {
     "addr": {
      "type": "integer",
      "description": "Entry point, decimal"
     },
     "name": {
      "type": "string"
     },
     "callees": {
      "type": "array",
      "items": {
       "type": "string"
      },
      "description": "Functions this one calls, by name; empty for leaves"
     }
    },
    "additionalProperties": false
   },
   "NamedAddr": {
    "type": "object",
    "properties": {
     "addr": {
      "type": "integer",
      "description": "Address as a decimal byte offset in the program's address space. Render as hex for display; pass back to addr parameters as a 0x-prefixed hex string."
     },
     "name": {
      "type": "string"
     }
    },
    "additionalProperties": false
   },
   "Instruction": {
    "type": "object",
    "properties": {
     "addr": {
      "type": "integer",
      "description": "Address as a decimal byte offset in the program's address space. Render as hex for display; pass back to addr parameters as a 0x-prefixed hex string."
     },
     "mnemonic": {
      "type": "string"
     },
     "text": {
      "type": "string"
     },
     "length": {
      "type": "integer"
     },
     "flow": {
      "type": "string",
      "description": "Control-flow class, e.g. FALL_THROUGH, UNCONDITIONAL_CALL"
     },
     "bytes": {
      "type": "string",
      "description": "Encoding as lowercase hex"
     },
     "operands": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "text": {
         "type": "string"
        },
        "type": {
         "type": "string"
        },
        "refers": {
         "type": "integer",
         "description": "Address the operand refers to, decimal; absent when none"
        }
       },
       "additionalProperties": false,
       "required": [
        "text",
        "type"
       ]
      }
     },
     "pcode": {
      "type": "array",
      "items": {
       "type": "string"
      },
      "description": "The instruction's p-code ops, one string each"
     }
    },
    "additionalProperties": false
   },
   "ResolveAddr": {
    "type": "object",
    "properties": {
     "addr": {
      "type": "integer",
      "description": "Address as a decimal byte offset in the program's address space. Render as hex for display; pass back to addr parameters as a 0x-prefixed hex string."
     },
     "name": {
      "type": "string",
      "description": "Containing function"
     },
     "size": {
      "type": "integer"
     },
     "end": {
      "type": "integer"
     }
    },
    "additionalProperties": false
   },
   "Signature": {
    "type": "object",
    "properties": {
     "addr": {
      "type": "integer",
      "description": "Address as a decimal byte offset in the program's address space. Render as hex for display; pass back to addr parameters as a 0x-prefixed hex string."
     },
     "name": {
      "type": "string"
     },
     "signature": {
      "type": "string",
      "description": "Full C prototype"
     },
     "callingConvention": {
      "type": "string"
     },
     "callingConventions": {
      "type": "array",
      "items": {
       "type": "string"
      },
      "description": "Conventions this program accepts"
     }
    },
    "additionalProperties": false
   },
   "StringItem": {
    "type": "object",
    "properties": {
     "vaddr": {
      "type": "integer",
      "description": "Address as a decimal byte offset in the program's address space. Render as hex for display; pass back to addr parameters as a 0x-prefixed hex string."
     },
     "paddr": {
      "type": "integer",
      "description": "File offset"
     },
     "size": {
      "type": "integer",
      "description": "Bytes including terminator"
     },
     "length": {
      "type": "integer",
      "description": "Characters"
     },
     "section": {
      "type": "string"
     },
     "type": {
      "type": "string",
      "description": "E.g. TerminatedCString, unicode"
     },
     "string": {
      "type": "string",
      "description": "The text itself"
     }
    },
    "additionalProperties": false
   },
   "Symbol": {
    "type": "object",
    "properties": {
     "name": {
      "type": "string"
     },
     "flagname": {
      "type": "string"
     },
     "realname": {
      "type": "string"
     },
     "ordinal": {
      "type": "integer"
     },
     "bind": {
      "type": "string"
     },
     "type": {
      "type": "string"
     },
     "size": {
      "type": "integer"
     },
     "vaddr": {
      "type": "integer",
      "description": "Address as a decimal byte offset in the program's address space. Render as hex for display; pass back to addr parameters as a 0x-prefixed hex string."
     },
     "paddr": {
      "type": "integer"
     },
     "is_imported": {
      "type": "boolean"
     }
    },
    "additionalProperties": false
   },
   "Import": {
    "type": "object",
    "properties": {
     "ordinal": {
      "type": "integer"
     },
     "bind": {
      "type": "string"
     },
     "type": {
      "type": "string"
     },
     "name": {
      "type": "string"
     },
     "plt": {
      "type": "integer",
      "description": "Thunk address, decimal"
     }
    },
    "additionalProperties": false
   },
   "Types": {
    "type": "object",
    "properties": {
     "types": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "type": {
         "type": "string",
         "description": "Type name"
        },
        "size": {
         "type": "integer",
         "description": "Bytes"
        },
        "format": {
         "type": "string",
         "description": "Category path in Ghidra's type manager"
        },
        "kind": {
         "type": "string",
         "description": "struct, union, enum, typedef, funcdef, pointer, array or builtin"
        }
       },
       "additionalProperties": false
      }
     }
    },
    "additionalProperties": false
   },
   "SearchHit": {
    "type": "object",
    "properties": {
     "addr": {
      "type": "integer",
      "description": "Address as a decimal byte offset in the program's address space. Render as hex for display; pass back to addr parameters as a 0x-prefixed hex string."
     },
     "type": {
      "type": "string",
      "description": "What matched: string, bytes, or similar"
     },
     "data": {
      "type": "string",
      "description": "The matching text or bytes"
     }
    },
    "additionalProperties": false
   },
   "Comment": {
    "type": "object",
    "properties": {
     "offset": {
      "type": "integer",
      "description": "Address, decimal"
     },
     "name": {
      "type": "string",
      "description": "The comment text"
     },
     "author": {
      "type": "string",
      "description": "Username that wrote it"
     },
     "at": {
      "type": "integer",
      "description": "Unix epoch milliseconds"
     }
    },
    "additionalProperties": false
   },
   "Label": {
    "type": "object",
    "properties": {
     "addr": {
      "type": "integer",
      "description": "Address as a decimal byte offset in the program's address space. Render as hex for display; pass back to addr parameters as a 0x-prefixed hex string."
     },
     "name": {
      "type": "string"
     },
     "user": {
      "type": "boolean",
      "description": "True when a person named it rather than analysis"
     }
    },
    "additionalProperties": false
   },
   "Bookmark": {
    "type": "object",
    "properties": {
     "addr": {
      "type": "integer",
      "description": "Address as a decimal byte offset in the program's address space. Render as hex for display; pass back to addr parameters as a 0x-prefixed hex string."
     },
     "category": {
      "type": "string"
     },
     "comment": {
      "type": "string"
     }
    },
    "additionalProperties": false
   },
   "ChatMessage": {
    "type": "object",
    "properties": {
     "id": {
      "type": "string"
     },
     "role": {
      "type": "string",
      "enum": [
       "user",
       "agent",
       "system"
      ]
     },
     "author": {
      "type": "string"
     },
     "text": {
      "type": "string",
      "description": "Markdown"
     },
     "at": {
      "type": "integer",
      "description": "Unix epoch milliseconds"
     }
    },
    "additionalProperties": false
   },
   "Notes": {
    "type": "object",
    "properties": {
     "text": {
      "type": "string",
      "description": "The shared session notes, markdown"
     }
    },
    "additionalProperties": false,
    "required": [
     "text"
    ]
   },
   "ActivityEvent": {
    "type": "object",
    "properties": {
     "type": {
      "type": "string",
      "description": "Event name, e.g. functionRenamed, commentsChanged, notesChanged"
     },
     "userId": {
      "type": "string",
      "description": "Who did it"
     },
     "addr": {
      "type": "string",
      "description": "Affected address when the event has one, 0x-prefixed hex"
     },
     "command": {
      "type": "string"
     },
     "timestamp": {
      "type": "integer",
      "description": "Unix epoch milliseconds"
     }
    },
    "additionalProperties": true
   },
   "Layout": {
    "description": "The creator's saved dock layout, or null when none was saved. An opaque frontend structure; not useful outside the workspace.",
    "type": [
     "object",
     "null"
    ],
    "additionalProperties": true
   },
   "Ready": {
    "type": "object",
    "properties": {
     "ready": {
      "type": "boolean",
      "description": "Whether the session is open and answering. False means it is analysing or reopening; poll until true."
     }
    },
    "additionalProperties": false,
    "required": [
     "ready"
    ]
   },
   "ViewerSession": {
    "type": "object",
    "properties": {
     "name": {
      "type": "string",
      "description": "The binary's display name"
     },
     "status": {
      "type": "string",
      "enum": [
       "pending",
       "queued",
       "analyzing",
       "ready",
       "errored"
      ]
     },
     "canDownload": {
      "type": "boolean",
      "description": "Whether GET /download will serve the original binary"
     }
    },
    "additionalProperties": false,
    "required": [
     "name",
     "status",
     "canDownload"
    ]
   },
   "PublicPost": {
    "type": "object",
    "description": "A published writeup as a reader loads it: rendered prose plus everything needed to reach the frozen session it argues about.",
    "properties": {
     "slug": {
      "type": "string"
     },
     "title": {
      "type": "string"
     },
     "summary": {
      "type": "string"
     },
     "html": {
      "type": "string",
      "description": "The prose, rendered at publish. References are anchors carrying revspace-addr: / revspace-fn: hrefs."
     },
     "token": {
      "type": "string",
      "description": "The share token for the frozen session: the reader's whole capability."
     },
     "mcpUrl": {
      "type": "string",
      "description": "The post's MCP endpoint, so a reader's own agent can read the sample."
     },
     "meta": {
      "type": "object"
     },
     "allowDownload": {
      "type": "boolean",
      "description": "Whether the author published the sample itself."
     },
     "publishedAt": {
      "type": "integer",
      "format": "int64"
     },
     "updatedAt": {
      "type": "integer",
      "format": "int64"
     },
     "canDownload": {
      "type": "boolean",
      "description": "Whether this gateway will actually release it, which an operator can override. Downloading needs an account: see /api/p/{slug}/download."
     }
    }
   },
   "TypeDetail": {
    "type": "object",
    "properties": {
     "name": {
      "type": "string",
      "description": "Category path of the type"
     },
     "kind": {
      "type": "string",
      "description": "struct, union, enum, typedef, funcdef, pointer, array or builtin"
     },
     "size": {
      "type": "integer",
      "description": "Bytes"
     },
     "base": {
      "type": "string",
      "description": "Underlying type; typedefs only"
     },
     "members": {
      "type": "array",
      "description": "Fields for a struct or union, values for an enum",
      "items": {
       "type": "object",
       "properties": {
        "offset": {
         "type": "integer",
         "description": "Byte offset; composites only"
        },
        "name": {
         "type": "string",
         "description": "Field or constant name"
        },
        "type": {
         "type": "string",
         "description": "Field type; composites only"
        },
        "size": {
         "type": "integer",
         "description": "Field size; composites only"
        },
        "comment": {
         "type": "string",
         "description": "Field comment; composites only"
        },
        "value": {
         "type": "integer",
         "description": "Constant value; enums only"
        }
       }
      }
     }
    }
   },
   "TypeUses": {
    "type": "object",
    "description": "What deleting this type would revert to undefined",
    "properties": {
     "name": {
      "type": "string",
      "description": "Category path of the type"
     },
     "data": {
      "type": "integer",
      "description": "Defined data using it"
     },
     "variables": {
      "type": "integer",
      "description": "Function variables typed as it"
     },
     "types": {
      "type": "integer",
      "description": "Other types built from it"
     },
     "total": {
      "type": "integer",
      "description": "Sum of the three"
     }
    }
   },
   "Finding": {
    "type": "object",
    "description": "One structured claim a background agent run recorded. Append-only: a corrected finding is superseded by a newer one, never edited.",
    "properties": {
     "id": {
      "type": "string"
     },
     "agent": {
      "type": "string"
     },
     "userId": {
      "type": "string"
     },
     "claim": {
      "type": "string"
     },
     "addr": {
      "type": "string"
     },
     "confidence": {
      "type": "string",
      "enum": [
       "low",
       "medium",
       "high"
      ]
     },
     "createdAt": {
      "type": "integer"
     },
     "supersedes": {
      "type": "string"
     },
     "supersededBy": {
      "type": "string"
     }
    },
    "required": [
     "id",
     "claim",
     "createdAt"
    ]
   }
  }
 }
}
