[{"data":1,"prerenderedAt":1734},["ShallowReactive",2],{"navigation":3,"\u002Fdocs\u002Fruntime\u002Frest-api":314,"\u002Fdocs\u002Fruntime\u002Frest-api-surround":1729},[4,38,86,149,176,219,257,273],{"title":5,"path":6,"stem":7,"children":8,"icon":37},"Getting Started","\u002Fdocs\u002Fgetting-started","1.docs\u002F1.getting-started\u002F1.index",[9,12,17,22,27,32],{"title":10,"path":6,"stem":7,"icon":11},"Getting started","i-lucide-flag",{"title":13,"path":14,"stem":15,"icon":16},"Modules overview","\u002Fdocs\u002Fgetting-started\u002Fmodules-overview","1.docs\u002F1.getting-started\u002F2.modules-overview","i-lucide-boxes",{"title":18,"path":19,"stem":20,"icon":21},"Installation","\u002Fdocs\u002Fgetting-started\u002Finstallation","1.docs\u002F1.getting-started\u002F3.installation","i-lucide-download",{"title":23,"path":24,"stem":25,"icon":26},"License configuration","\u002Fdocs\u002Fgetting-started\u002Flicense-configuration","1.docs\u002F1.getting-started\u002F4.license-configuration","i-lucide-key-round",{"title":28,"path":29,"stem":30,"icon":31},"Your first app","\u002Fdocs\u002Fgetting-started\u002Ffirst-app","1.docs\u002F1.getting-started\u002F5.first-app","i-lucide-square-play",{"title":33,"path":34,"stem":35,"icon":36},"Project setup","\u002Fdocs\u002Fgetting-started\u002Fproject-setup","1.docs\u002F1.getting-started\u002F6.project-setup","i-lucide-package",false,{"title":39,"path":40,"stem":41,"children":42,"icon":45},"Core Concepts","\u002Fdocs\u002Fconcepts","1.docs\u002F2.concepts\u002F1.index",[43,46,51,56,61,66,71,76,81],{"title":44,"path":40,"stem":41,"icon":45},"Core concepts","i-lucide-book-open",{"title":47,"path":48,"stem":49,"icon":50},"Architecture","\u002Fdocs\u002Fconcepts\u002Farchitecture","1.docs\u002F2.concepts\u002F2.architecture","i-lucide-layers",{"title":52,"path":53,"stem":54,"icon":55},"Exactly-once semantics","\u002Fdocs\u002Fconcepts\u002Fexactly-once","1.docs\u002F2.concepts\u002F3.exactly-once","i-lucide-shield-check",{"title":57,"path":58,"stem":59,"icon":60},"Lanes and parallelism","\u002Fdocs\u002Fconcepts\u002Flanes-and-parallelism","1.docs\u002F2.concepts\u002F4.lanes-and-parallelism","i-lucide-split",{"title":62,"path":63,"stem":64,"icon":65},"State and thread-safety","\u002Fdocs\u002Fconcepts\u002Fstate-and-thread-safety","1.docs\u002F2.concepts\u002F5.state-and-thread-safety","i-lucide-lock",{"title":67,"path":68,"stem":69,"icon":70},"Event time and watermarks","\u002Fdocs\u002Fconcepts\u002Fevent-time-and-watermarks","1.docs\u002F2.concepts\u002F6.event-time-and-watermarks","i-lucide-clock",{"title":72,"path":73,"stem":74,"icon":75},"The configuration model","\u002Fdocs\u002Fconcepts\u002Fconfiguration-model","1.docs\u002F2.concepts\u002F7.configuration-model","i-lucide-sliders-horizontal",{"title":77,"path":78,"stem":79,"icon":80},"The error-handling model","\u002Fdocs\u002Fconcepts\u002Ferror-handling-model","1.docs\u002F2.concepts\u002F8.error-handling-model","i-lucide-triangle-alert",{"title":82,"path":83,"stem":84,"icon":85},"How StoatFlow differs from Kafka Streams","\u002Fdocs\u002Fconcepts\u002Fhow-stoatflow-differs-from-ks","1.docs\u002F2.concepts\u002F9.how-stoatflow-differs-from-ks","i-lucide-arrow-left-right",{"title":87,"path":88,"stem":89,"children":90,"icon":93},"Building Topologies","\u002Fdocs\u002Fbuilding","1.docs\u002F3.building\u002F1.index",[91,94,99,104,109,114,119,124,129,134,139,144],{"title":92,"path":88,"stem":89,"icon":93},"Building topologies","i-lucide-blocks",{"title":95,"path":96,"stem":97,"icon":98},"Error handling and DLQ","\u002Fdocs\u002Fbuilding\u002Ferror-handling-dlq","1.docs\u002F3.building\u002F10.error-handling-dlq","i-lucide-circle-x",{"title":100,"path":101,"stem":102,"icon":103},"State stores","\u002Fdocs\u002Fbuilding\u002Fstate-stores","1.docs\u002F3.building\u002F11.state-stores","i-lucide-database",{"title":105,"path":106,"stem":107,"icon":108},"Testing topologies","\u002Fdocs\u002Fbuilding\u002Ftesting","1.docs\u002F3.building\u002F12.testing","i-lucide-flask-conical",{"title":110,"path":111,"stem":112,"icon":113},"Sources and sinks","\u002Fdocs\u002Fbuilding\u002Fstreams-builder","1.docs\u002F3.building\u002F2.streams-builder","i-lucide-import",{"title":115,"path":116,"stem":117,"icon":118},"KStream and KTable operations","\u002Fdocs\u002Fbuilding\u002Fkstream-ktable","1.docs\u002F3.building\u002F3.kstream-ktable","i-lucide-waypoints",{"title":120,"path":121,"stem":122,"icon":123},"Aggregations","\u002Fdocs\u002Fbuilding\u002Faggregations","1.docs\u002F3.building\u002F4.aggregations","i-lucide-sigma",{"title":125,"path":126,"stem":127,"icon":128},"Windowing","\u002Fdocs\u002Fbuilding\u002Fwindowing","1.docs\u002F3.building\u002F5.windowing","i-lucide-calendar-clock",{"title":130,"path":131,"stem":132,"icon":133},"Joins","\u002Fdocs\u002Fbuilding\u002Fjoins","1.docs\u002F3.building\u002F6.joins","i-lucide-git-merge",{"title":135,"path":136,"stem":137,"icon":138},"The Processor API","\u002Fdocs\u002Fbuilding\u002Fprocessor-api","1.docs\u002F3.building\u002F7.processor-api","i-lucide-cpu",{"title":140,"path":141,"stem":142,"icon":143},"Scheduled sources","\u002Fdocs\u002Fbuilding\u002Fscheduled-sources","1.docs\u002F3.building\u002F8.scheduled-sources","i-lucide-timer",{"title":145,"path":146,"stem":147,"icon":148},"Serdes and Avro","\u002Fdocs\u002Fbuilding\u002Fserdes","1.docs\u002F3.building\u002F9.serdes","i-lucide-binary",{"title":150,"path":151,"stem":152,"children":153,"icon":75},"Configuration","\u002Fdocs\u002Fconfiguration","1.docs\u002F4.configuration\u002F1.index",[154,156,161,166,171],{"title":155,"path":151,"stem":152,"icon":75},"How configuration works",{"title":157,"path":158,"stem":159,"icon":160},"Engine configuration (:core)","\u002Fdocs\u002Fconfiguration\u002Fcore-config","1.docs\u002F4.configuration\u002F2.core-config","i-lucide-settings-2",{"title":162,"path":163,"stem":164,"icon":165},"Runtime configuration (:runtime)","\u002Fdocs\u002Fconfiguration\u002Fruntime-config","1.docs\u002F4.configuration\u002F3.runtime-config","i-lucide-server-cog",{"title":167,"path":168,"stem":169,"icon":170},"Defaults, adaptivity, and presets","\u002Fdocs\u002Fconfiguration\u002Fdefaults-and-presets","1.docs\u002F4.configuration\u002F4.defaults-and-presets","i-lucide-gauge",{"title":172,"path":173,"stem":174,"icon":175},"Kafka client configuration","\u002Fdocs\u002Fconfiguration\u002Fkafka-client-config","1.docs\u002F4.configuration\u002F5.kafka-client-config","i-lucide-plug",{"title":177,"path":178,"stem":179,"children":180,"icon":183},"Running in Production","\u002Fdocs\u002Fruntime","1.docs\u002F5.runtime\u002F1.index",[181,184,189,194,199,204,209,214],{"title":182,"path":178,"stem":179,"icon":183},"The runtime","i-lucide-server",{"title":185,"path":186,"stem":187,"icon":188},"The REST API","\u002Fdocs\u002Fruntime\u002Frest-api","1.docs\u002F5.runtime\u002F2.rest-api","i-lucide-globe",{"title":190,"path":191,"stem":192,"icon":193},"Health checks","\u002Fdocs\u002Fruntime\u002Fhealth-checks","1.docs\u002F5.runtime\u002F3.health-checks","i-lucide-heart-pulse",{"title":195,"path":196,"stem":197,"icon":198},"Metrics","\u002Fdocs\u002Fruntime\u002Fmetrics","1.docs\u002F5.runtime\u002F4.metrics","i-lucide-activity",{"title":200,"path":201,"stem":202,"icon":203},"Pause and resume","\u002Fdocs\u002Fruntime\u002Fpause-unpause","1.docs\u002F5.runtime\u002F5.pause-unpause","i-lucide-pause",{"title":205,"path":206,"stem":207,"icon":208},"Plugins and lifecycle hooks","\u002Fdocs\u002Fruntime\u002Fplugins","1.docs\u002F5.runtime\u002F6.plugins","i-lucide-puzzle",{"title":210,"path":211,"stem":212,"icon":213},"Docker images","\u002Fdocs\u002Fruntime\u002Fdocker","1.docs\u002F5.runtime\u002F7.docker","i-lucide-container",{"title":215,"path":216,"stem":217,"icon":218},"GraalVM native image","\u002Fdocs\u002Fruntime\u002Fnative-image","1.docs\u002F5.runtime\u002F8.native-image","i-lucide-zap",{"title":220,"path":221,"stem":222,"children":223,"icon":226},"Deploying & Operating","\u002Fdocs\u002Foperating","1.docs\u002F6.operating\u002F1.index",[224,227,232,237,242,247,252],{"title":225,"path":221,"stem":222,"icon":226},"Deploying and operating","i-lucide-life-buoy",{"title":228,"path":229,"stem":230,"icon":231},"Running on Kubernetes","\u002Fdocs\u002Foperating\u002Fkubernetes","1.docs\u002F6.operating\u002F2.kubernetes","i-lucide-ship",{"title":233,"path":234,"stem":235,"icon":236},"High availability","\u002Fdocs\u002Foperating\u002Fhigh-availability","1.docs\u002F6.operating\u002F3.high-availability","i-lucide-copy",{"title":238,"path":239,"stem":240,"icon":241},"Liveness and readiness probes","\u002Fdocs\u002Foperating\u002Fprobes","1.docs\u002F6.operating\u002F4.probes","i-lucide-stethoscope",{"title":243,"path":244,"stem":245,"icon":246},"Observability","\u002Fdocs\u002Foperating\u002Fobservability","1.docs\u002F6.operating\u002F5.observability","i-lucide-telescope",{"title":248,"path":249,"stem":250,"icon":251},"Tuning under load","\u002Fdocs\u002Foperating\u002Ftuning","1.docs\u002F6.operating\u002F6.tuning","i-lucide-sliders",{"title":253,"path":254,"stem":255,"icon":256},"Production checklist","\u002Fdocs\u002Foperating\u002Fproduction-checklist","1.docs\u002F6.operating\u002F7.production-checklist","i-lucide-clipboard-check",{"title":258,"path":259,"stem":260,"children":261,"icon":85},"Migrating from Kafka Streams","\u002Fdocs\u002Fmigration","1.docs\u002F7.migration\u002F1.index",[262,263,268],{"title":258,"path":259,"stem":260,"icon":85},{"title":264,"path":265,"stem":266,"icon":267},"Migration without carrying state","\u002Fdocs\u002Fmigration\u002Fwithout-data-migration","1.docs\u002F7.migration\u002F2.without-data-migration","i-lucide-sparkles",{"title":269,"path":270,"stem":271,"icon":272},"Migration carrying state","\u002Fdocs\u002Fmigration\u002Fwith-data-migration","1.docs\u002F7.migration\u002F3.with-data-migration","i-lucide-database-backup",{"title":274,"path":275,"stem":276,"children":277,"icon":279},"Reference","\u002Fdocs\u002Freference","1.docs\u002F8.reference\u002F1.index",[278,280,285,290,295,300,305,309],{"title":274,"path":275,"stem":276,"icon":279},"i-lucide-list",{"title":281,"path":282,"stem":283,"icon":284},"Configuration reference","\u002Fdocs\u002Freference\u002Fconfiguration-reference","1.docs\u002F8.reference\u002F2.configuration-reference","i-lucide-table",{"title":286,"path":287,"stem":288,"icon":289},"REST API reference","\u002Fdocs\u002Freference\u002Frest-api-reference","1.docs\u002F8.reference\u002F3.rest-api-reference","i-lucide-network",{"title":291,"path":292,"stem":293,"icon":294},"Gradle plugin reference","\u002Fdocs\u002Freference\u002Fgradle-plugin-reference","1.docs\u002F8.reference\u002F4.gradle-plugin-reference","i-lucide-box",{"title":296,"path":297,"stem":298,"icon":299},"Maven reference","\u002Fdocs\u002Freference\u002Fmaven-reference","1.docs\u002F8.reference\u002F5.maven-reference","i-simple-icons-apachemaven",{"title":301,"path":302,"stem":303,"icon":304},"Kafka Streams compatibility matrix","\u002Fdocs\u002Freference\u002Fks-compatibility-matrix","1.docs\u002F8.reference\u002F6.ks-compatibility-matrix","i-lucide-table-2",{"title":306,"path":307,"stem":308,"icon":170},"Metrics reference","\u002Fdocs\u002Freference\u002Fmetrics-reference","1.docs\u002F8.reference\u002F7.metrics-reference",{"title":310,"path":311,"stem":312,"icon":313},"Glossary","\u002Fdocs\u002Freference\u002Fglossary","1.docs\u002F8.reference\u002F8.glossary","i-lucide-book-a",{"id":315,"title":185,"body":316,"description":1722,"extension":1723,"meta":1724,"navigation":1725,"pageType":1726,"path":186,"seo":1727,"stem":187,"__hash__":1728},"docs\u002F1.docs\u002F5.runtime\u002F2.rest-api.md",{"type":317,"value":318,"toc":1709},"minimark",[319,328,405,410,420,531,534,555,600,613,617,620,665,674,688,693,744,748,751,805,812,873,881,903,907,910,972,987,1001,1010,1024,1032,1055,1064,1068,1071,1107,1126,1149,1163,1167,1170,1213,1260,1276,1279,1293,1361,1393,1418,1422,1447,1455,1469,1484,1489,1492,1518,1532,1548,1552,1555,1597,1611,1653,1684,1694,1698,1705],[320,321,322,323,327],"p",{},"The ",[324,325,326],"code",{},":runtime"," module starts a small HTTP server alongside your topology. It serves operational endpoints — metadata, topology views, live state and progress, health probes, control actions, license state, Prometheus metrics, and freeze diagnostics. Everything below is what an operator reaches for from a shell, a dashboard, or a Kubernetes probe.",[329,330,331],"tldr-panel",{},[332,333,334,350,364,376,396],"ul",{},[335,336,337,341,342,345,346,349],"li",{},[338,339,340],"strong",{},"Server:"," JDK built-in HTTP server on ",[324,343,344],{},"0.0.0.0:8080"," by default — enable and configure it under ",[324,347,348],{},"runtime.http",".",[335,351,352,355,356,359,360,363],{},[338,353,354],{},"Read endpoints:"," ",[324,357,358],{},"GET"," — JSON (and a few negotiate text\u002FYAML via the ",[324,361,362],{},"Accept"," header).",[335,365,366,355,369,372,373,349],{},[338,367,368],{},"Control endpoints:",[324,370,371],{},"POST \u002Fpause"," and ",[324,374,375],{},"POST \u002Funpause",[335,377,378,355,381,372,384,387,388,391,392,395],{},[338,379,380],{},"Probes:",[324,382,383],{},"GET \u002Fhealth\u002Flive",[324,385,386],{},"GET \u002Fhealth\u002Fready"," — ",[324,389,390],{},"200"," UP, ",[324,393,394],{},"503"," DOWN.",[335,397,398,401,402,349],{},[338,399,400],{},"Reference:"," every field and response shape lives in the ",[403,404,286],"a",{"href":287},[406,407,409],"h2",{"id":408},"enabling-the-server","Enabling the server",[320,411,412,413,415,416,419],{},"The HTTP server is configured under ",[324,414,348],{},". It's enabled by default; metrics live under ",[324,417,418],{},"runtime.metrics",":",[421,422,427],"pre",{"className":423,"code":424,"language":425,"meta":426,"style":426},"language-yaml shiki shiki-themes vitesse-light","runtime:\n  http:\n    enabled: true\n    port: 8080          # default\n    host: 0.0.0.0       # default — all interfaces\n    debug:\n      enabled: true     # default — \u002Fdebug\u002F* endpoints\n  metrics:\n    enabled: true\n","yaml","",[324,428,429,442,450,462,478,492,500,514,522],{"__ignoreMap":426},[430,431,434,438],"span",{"class":432,"line":433},"line",1,[430,435,437],{"class":436},"su6XF","runtime",[430,439,441],{"class":440},"sYZai",":\n",[430,443,445,448],{"class":432,"line":444},2,[430,446,447],{"class":436},"  http",[430,449,441],{"class":440},[430,451,453,456,458],{"class":432,"line":452},3,[430,454,455],{"class":436},"    enabled",[430,457,419],{"class":440},[430,459,461],{"class":460},"sbBg2"," true\n",[430,463,465,468,470,474],{"class":432,"line":464},4,[430,466,467],{"class":436},"    port",[430,469,419],{"class":440},[430,471,473],{"class":472},"s-TwI"," 8080",[430,475,477],{"class":476},"s8zF2","          # default\n",[430,479,481,484,486,489],{"class":432,"line":480},5,[430,482,483],{"class":436},"    host",[430,485,419],{"class":440},[430,487,488],{"class":472}," 0.0.0.0",[430,490,491],{"class":476},"       # default — all interfaces\n",[430,493,495,498],{"class":432,"line":494},6,[430,496,497],{"class":436},"    debug",[430,499,441],{"class":440},[430,501,503,506,508,511],{"class":432,"line":502},7,[430,504,505],{"class":436},"      enabled",[430,507,419],{"class":440},[430,509,510],{"class":460}," true",[430,512,513],{"class":476},"     # default — \u002Fdebug\u002F* endpoints\n",[430,515,517,520],{"class":432,"line":516},8,[430,518,519],{"class":436},"  metrics",[430,521,441],{"class":440},[430,523,525,527,529],{"class":432,"line":524},9,[430,526,455],{"class":436},[430,528,419],{"class":440},[430,530,461],{"class":460},[320,532,533],{},"A quick liveness check from the shell:",[421,535,539],{"className":536,"code":537,"language":538,"meta":426,"style":426},"language-bash shiki shiki-themes vitesse-light","curl -s localhost:8080\u002Fhealth\u002Fready\n","bash",[324,540,541],{"__ignoreMap":426},[430,542,543,547,551],{"class":432,"line":433},[430,544,546],{"class":545},"sySUi","curl",[430,548,550],{"class":549},"sEi1f"," -s",[430,552,554],{"class":553},"spphp"," localhost:8080\u002Fhealth\u002Fready\n",[556,557,560],"callout",{"color":558,"icon":559},"warning","i-lucide-shield",[320,561,562,563,566,567,570,571,574,575,578,579,582,583,372,586,589,590,593,594,372,597,349],{},"Several endpoints expose internals or customer-identifying data — ",[324,564,565],{},"\u002Flicense"," (license ID, customer name, machine counts), ",[324,568,569],{},"\u002Fconfig",", ",[324,572,573],{},"\u002Finfo",", the ",[324,576,577],{},"\u002Ftopology\u002F*"," views, and ",[324,580,581],{},"\u002Fdebug\u002F*",". Expose only ",[324,584,585],{},"\u002Fhealth\u002Flive",[324,587,588],{},"\u002Fhealth\u002Fready"," through internet-facing ingress; keep the rest on the in-cluster ",[324,591,592],{},"Service",". See ",[403,595,596],{"href":229},"Kubernetes",[403,598,599],{"href":239},"Probes",[320,601,602,603,605,606,609,610,612],{},"All read endpoints are ",[324,604,358],{},". Calling one with the wrong method returns ",[324,607,608],{},"405",". Before the engine has finished starting, endpoints that depend on it return ",[324,611,394],{}," with a short JSON error.",[406,614,616],{"id":615},"metadata","Metadata",[320,618,619],{},"Use these to confirm what's deployed and how it's configured.",[621,622,623,639],"table",{},[624,625,626],"thead",{},[627,628,629,633,636],"tr",{},[630,631,632],"th",{},"Endpoint",[630,634,635],{},"Method",[630,637,638],{},"Purpose",[640,641,642,654],"tbody",{},[627,643,644,649,651],{},[645,646,647],"td",{},[324,648,573],{},[645,650,358],{},[645,652,653],{},"Application ID, JVM and Kafka info, uptime, current state, and the list of registered endpoints.",[627,655,656,660,662],{},[645,657,658],{},[324,659,569],{},[645,661,358],{},[645,663,664],{},"The merged effective configuration, with secrets masked.",[320,666,667,669,670,673],{},[324,668,573],{}," is the fastest way to see what's running and which endpoints this build exposes — the ",[324,671,672],{},"endpoints"," array is generated from the actual handler registration:",[421,675,677],{"className":536,"code":676,"language":538,"meta":426,"style":426},"curl -s localhost:8080\u002Finfo\n",[324,678,679],{"__ignoreMap":426},[430,680,681,683,685],{"class":432,"line":433},[430,682,546],{"class":545},[430,684,550],{"class":549},[430,686,687],{"class":553}," localhost:8080\u002Finfo\n",[320,689,690,692],{},[324,691,569],{}," content-negotiates: it returns YAML by default (more readable), or JSON if you ask for it. Passwords, secrets, and tokens are masked in the output.",[421,694,696],{"className":536,"code":695,"language":538,"meta":426,"style":426},"# YAML (default)\ncurl -s localhost:8080\u002Fconfig\n\n# JSON\ncurl -s -H 'Accept: application\u002Fjson' localhost:8080\u002Fconfig\n",[324,697,698,703,712,718,723],{"__ignoreMap":426},[430,699,700],{"class":432,"line":433},[430,701,702],{"class":476},"# YAML (default)\n",[430,704,705,707,709],{"class":432,"line":444},[430,706,546],{"class":545},[430,708,550],{"class":549},[430,710,711],{"class":553}," localhost:8080\u002Fconfig\n",[430,713,714],{"class":432,"line":452},[430,715,717],{"emptyLinePlaceholder":716},true,"\n",[430,719,720],{"class":432,"line":464},[430,721,722],{"class":476},"# JSON\n",[430,724,725,727,729,732,736,739,742],{"class":432,"line":480},[430,726,546],{"class":545},[430,728,550],{"class":549},[430,730,731],{"class":549}," -H",[430,733,735],{"class":734},"sSP4y"," '",[430,737,738],{"class":553},"Accept: application\u002Fjson",[430,740,741],{"class":734},"'",[430,743,711],{"class":553},[406,745,747],{"id":746},"topology","Topology",[320,749,750],{},"Three views of the same topology, for different audiences.",[621,752,753,763],{},[624,754,755],{},[627,756,757,759,761],{},[630,758,632],{},[630,760,635],{},[630,762,638],{},[640,764,765,777,793],{},[627,766,767,772,774],{},[645,768,769],{},[324,770,771],{},"\u002Ftopology",[645,773,358],{},[645,775,776],{},"StoatFlow-native view with rich metadata (scheduled sources, store names, sub-topology structure).",[627,778,779,784,786],{},[645,780,781],{},[324,782,783],{},"\u002Ftopology\u002Fks",[645,785,358],{},[645,787,788,789,792],{},"Kafka Streams-compatible view, matching ",[324,790,791],{},"Topology#describe()"," output.",[627,794,795,800,802],{},[645,796,797],{},[324,798,799],{},"\u002Ftopology\u002Fcompiled",[645,801,358],{},[645,803,804],{},"The compiled, runtime-internal representation produced by the topology compiler.",[320,806,807,372,809,811],{},[324,808,771],{},[324,810,783],{}," return a human-readable text description by default, or JSON when you request it:",[421,813,815],{"className":536,"code":814,"language":538,"meta":426,"style":426},"# Text (default)\ncurl -s localhost:8080\u002Ftopology\n\n# JSON\ncurl -s -H 'Accept: application\u002Fjson' localhost:8080\u002Ftopology\n\n# Kafka Streams-compatible description\ncurl -s localhost:8080\u002Ftopology\u002Fks\n",[324,816,817,822,831,835,839,855,859,864],{"__ignoreMap":426},[430,818,819],{"class":432,"line":433},[430,820,821],{"class":476},"# Text (default)\n",[430,823,824,826,828],{"class":432,"line":444},[430,825,546],{"class":545},[430,827,550],{"class":549},[430,829,830],{"class":553}," localhost:8080\u002Ftopology\n",[430,832,833],{"class":432,"line":452},[430,834,717],{"emptyLinePlaceholder":716},[430,836,837],{"class":432,"line":464},[430,838,722],{"class":476},[430,840,841,843,845,847,849,851,853],{"class":432,"line":480},[430,842,546],{"class":545},[430,844,550],{"class":549},[430,846,731],{"class":549},[430,848,735],{"class":734},[430,850,738],{"class":553},[430,852,741],{"class":734},[430,854,830],{"class":553},[430,856,857],{"class":432,"line":494},[430,858,717],{"emptyLinePlaceholder":716},[430,860,861],{"class":432,"line":502},[430,862,863],{"class":476},"# Kafka Streams-compatible description\n",[430,865,866,868,870],{"class":432,"line":516},[430,867,546],{"class":545},[430,869,550],{"class":549},[430,871,872],{"class":553}," localhost:8080\u002Ftopology\u002Fks\n",[320,874,875,877,878,880],{},[324,876,799],{}," reflects how the engine actually compiled and laid out your topology, which can differ from the logical DSL view (for example where key-changing operations introduce sub-topology boundaries). It's primarily a diagnostic view; it returns ",[324,879,394],{}," until the application has started.",[421,882,884],{"className":536,"code":883,"language":538,"meta":426,"style":426},"curl -s -H 'Accept: application\u002Fjson' localhost:8080\u002Ftopology\u002Fcompiled\n",[324,885,886],{"__ignoreMap":426},[430,887,888,890,892,894,896,898,900],{"class":432,"line":433},[430,889,546],{"class":545},[430,891,550],{"class":549},[430,893,731],{"class":549},[430,895,735],{"class":734},[430,897,738],{"class":553},[430,899,741],{"class":734},[430,901,902],{"class":553}," localhost:8080\u002Ftopology\u002Fcompiled\n",[406,904,906],{"id":905},"state-and-progress","State and progress",[320,908,909],{},"These show whether the application is making progress and where it's at — lifecycle state, consumer assignment, offset lag, and event-time watermarks.",[621,911,912,922],{},[624,913,914],{},[627,915,916,918,920],{},[630,917,632],{},[630,919,635],{},[630,921,638],{},[640,923,924,936,948,960],{},[627,925,926,931,933],{},[645,927,928],{},[324,929,930],{},"\u002Fstate",[645,932,358],{},[645,934,935],{},"Current lifecycle state, when it was entered, and the recent state-transition history.",[627,937,938,943,945],{},[645,939,940],{},[324,941,942],{},"\u002Fconsumer",[645,944,358],{},[645,946,947],{},"Consumer group metadata, source subscription, last commit time, and per-partition buffer fill + pause state.",[627,949,950,955,957],{},[645,951,952],{},[324,953,954],{},"\u002Foffsets",[645,956,358],{},[645,958,959],{},"Per-partition committed offsets and lag for source topics, plus committed changelog offsets per state store.",[627,961,962,967,969],{},[645,963,964],{},[324,965,966],{},"\u002Fwatermarks",[645,968,358],{},[645,970,971],{},"Global and per-partition event-time watermarks, idle flags, and last event times.",[320,973,974,976,977,570,980,570,983,986],{},[324,975,930],{}," is the lifecycle picture — is the app ",[324,978,979],{},"RUNNING",[324,981,982],{},"DRAINING",[324,984,985],{},"PAUSED",", restoring, shutting down?",[421,988,990],{"className":536,"code":989,"language":538,"meta":426,"style":426},"curl -s localhost:8080\u002Fstate\n",[324,991,992],{"__ignoreMap":426},[430,993,994,996,998],{"class":432,"line":433},[430,995,546],{"class":545},[430,997,550],{"class":549},[430,999,1000],{"class":553}," localhost:8080\u002Fstate\n",[320,1002,1003,1005,1006,1009],{},[324,1004,954],{}," answers \"are we falling behind?\" — it reports per-partition lag and a ",[324,1007,1008],{},"totalLag"," summary, derived from locally cached values (no Kafka RPCs on the request path):",[421,1011,1013],{"className":536,"code":1012,"language":538,"meta":426,"style":426},"curl -s localhost:8080\u002Foffsets\n",[324,1014,1015],{"__ignoreMap":426},[430,1016,1017,1019,1021],{"class":432,"line":433},[430,1018,546],{"class":545},[430,1020,550],{"class":549},[430,1022,1023],{"class":553}," localhost:8080\u002Foffsets\n",[320,1025,1026,1028,1029,1031],{},[324,1027,942],{}," adds the consumer-group angle (member ID, generation, subscription) and shows per-partition buffer utilisation, so you can see whether any partition is paused under backpressure. ",[324,1030,966],{}," exposes event-time progress — useful when windowed or timer-driven logic seems to be waiting.",[421,1033,1035],{"className":536,"code":1034,"language":538,"meta":426,"style":426},"curl -s localhost:8080\u002Fconsumer\ncurl -s localhost:8080\u002Fwatermarks\n",[324,1036,1037,1046],{"__ignoreMap":426},[430,1038,1039,1041,1043],{"class":432,"line":433},[430,1040,546],{"class":545},[430,1042,550],{"class":549},[430,1044,1045],{"class":553}," localhost:8080\u002Fconsumer\n",[430,1047,1048,1050,1052],{"class":432,"line":444},[430,1049,546],{"class":545},[430,1051,550],{"class":549},[430,1053,1054],{"class":553}," localhost:8080\u002Fwatermarks\n",[320,1056,1057,1058,1060,1061,1063],{},"See ",[403,1059,67],{"href":68}," for how watermarks advance, and ",[403,1062,243],{"href":244}," for turning these into dashboards.",[406,1065,1067],{"id":1066},"health-probes","Health probes",[320,1069,1070],{},"Kubernetes-style liveness and readiness, with separate indicator sets.",[621,1072,1073,1083],{},[624,1074,1075],{},[627,1076,1077,1079,1081],{},[630,1078,632],{},[630,1080,635],{},[630,1082,638],{},[640,1084,1085,1096],{},[627,1086,1087,1091,1093],{},[645,1088,1089],{},[324,1090,585],{},[645,1092,358],{},[645,1094,1095],{},"Liveness — is the process healthy enough to keep alive?",[627,1097,1098,1102,1104],{},[645,1099,1100],{},[324,1101,588],{},[645,1103,358],{},[645,1105,1106],{},"Readiness — is the app ready to receive\u002Fprocess traffic?",[320,1108,1109,1110,1112,1113,1116,1117,1112,1119,355,1122,1125],{},"Both return ",[324,1111,390],{}," with ",[324,1114,1115],{},"{\"status\":\"UP\", ...}"," when all relevant indicators pass, or ",[324,1118,394],{},[324,1120,1121],{},"status",[324,1123,1124],{},"DOWN"," otherwise. Liveness stays UP through transient states (startup, shutdown, and license issues a restart can't fix) so orchestrators don't needlessly restart the process; readiness goes DOWN during startup, state restoration, and shutdown.",[421,1127,1129],{"className":536,"code":1128,"language":538,"meta":426,"style":426},"curl -i localhost:8080\u002Fhealth\u002Flive\ncurl -i localhost:8080\u002Fhealth\u002Fready\n",[324,1130,1131,1141],{"__ignoreMap":426},[430,1132,1133,1135,1138],{"class":432,"line":433},[430,1134,546],{"class":545},[430,1136,1137],{"class":549}," -i",[430,1139,1140],{"class":553}," localhost:8080\u002Fhealth\u002Flive\n",[430,1142,1143,1145,1147],{"class":432,"line":444},[430,1144,546],{"class":545},[430,1146,1137],{"class":549},[430,1148,554],{"class":553},[320,1150,1151,1152,372,1154,593,1157,1159,1160,1162],{},"The response lists each component indicator (engine state, Kafka broker connectivity, Schema Registry if configured, license state) with its own ",[324,1153,1121],{},[324,1155,1156],{},"details",[403,1158,190],{"href":191}," for the indicators and ",[403,1161,599],{"href":239}," for wiring them to Kubernetes.",[406,1164,1166],{"id":1165},"control","Control",[320,1168,1169],{},"Pause and resume processing at runtime — for maintenance, draining, or controlled investigation.",[621,1171,1172,1182],{},[624,1173,1174],{},[627,1175,1176,1178,1180],{},[630,1177,632],{},[630,1179,635],{},[630,1181,638],{},[640,1183,1184,1199],{},[627,1185,1186,1191,1194],{},[645,1187,1188],{},[324,1189,1190],{},"\u002Fpause",[645,1192,1193],{},"POST",[645,1195,1196,1197,349],{},"Pause processing — drains in-flight work, then reaches ",[324,1198,985],{},[627,1200,1201,1206,1208],{},[645,1202,1203],{},[324,1204,1205],{},"\u002Funpause",[645,1207,1193],{},[645,1209,1210,1211,349],{},"Resume processing — returns to ",[324,1212,979],{},[421,1214,1216],{"className":536,"code":1215,"language":538,"meta":426,"style":426},"curl -s -X POST localhost:8080\u002Fpause\n# -> {\"status\":\"pausing\",\"state\":\"DRAINING\"}\n\ncurl -s -X POST localhost:8080\u002Funpause\n# -> {\"status\":\"resumed\",\"state\":\"RUNNING\"}\n",[324,1217,1218,1233,1238,1242,1255],{"__ignoreMap":426},[430,1219,1220,1222,1224,1227,1230],{"class":432,"line":433},[430,1221,546],{"class":545},[430,1223,550],{"class":549},[430,1225,1226],{"class":549}," -X",[430,1228,1229],{"class":553}," POST",[430,1231,1232],{"class":553}," localhost:8080\u002Fpause\n",[430,1234,1235],{"class":432,"line":444},[430,1236,1237],{"class":476},"# -> {\"status\":\"pausing\",\"state\":\"DRAINING\"}\n",[430,1239,1240],{"class":432,"line":452},[430,1241,717],{"emptyLinePlaceholder":716},[430,1243,1244,1246,1248,1250,1252],{"class":432,"line":464},[430,1245,546],{"class":545},[430,1247,550],{"class":549},[430,1249,1226],{"class":549},[430,1251,1229],{"class":553},[430,1253,1254],{"class":553}," localhost:8080\u002Funpause\n",[430,1256,1257],{"class":432,"line":480},[430,1258,1259],{"class":476},"# -> {\"status\":\"resumed\",\"state\":\"RUNNING\"}\n",[320,1261,1262,1263,1265,1266,1269,1270,593,1272,1275],{},"Both are ",[324,1264,1193],{},". A request that can't be honoured from the current state returns ",[324,1267,1268],{},"400"," with an explanatory error; if the engine isn't initialised yet you get ",[324,1271,394],{},[403,1273,1274],{"href":201},"Pause and unpause"," for the state semantics and what \"draining\" guarantees.",[406,1277,233],{"id":1278},"high-availability",[320,1280,1281,1282,1285,1286,1289,1290,349],{},"Registered only when ",[403,1283,1284],{"href":234},"hot standby"," is enabled (",[324,1287,1288],{},"ha.mode != off","); otherwise these paths return ",[324,1291,1292],{},"404",[621,1294,1295,1305],{},[624,1296,1297],{},[627,1298,1299,1301,1303],{},[630,1300,632],{},[630,1302,635],{},[630,1304,638],{},[640,1306,1307,1319,1331,1347],{},[627,1308,1309,1314,1316],{},[645,1310,1311],{},[324,1312,1313],{},"\u002Fha\u002Fstatus",[645,1315,358],{},[645,1317,1318],{},"This pod's view of the cluster: role, replication lag, ready-standby count, promotion-token epoch, and observed peers.",[627,1320,1321,1326,1328],{},[645,1322,1323],{},[324,1324,1325],{},"\u002Fha\u002Fswitch",[645,1327,1193],{},[645,1329,1330],{},"Swap roles — the active drains and the peer promotes.",[627,1332,1333,1338,1340],{},[645,1334,1335],{},[324,1336,1337],{},"\u002Fha\u002Fpromote",[645,1339,1193],{},[645,1341,1342,1343,1346],{},"Promote a specific standby (",[324,1344,1345],{},"?pod=\u003Cid>",").",[627,1348,1349,1354,1356],{},[645,1350,1351],{},[324,1352,1353],{},"\u002Fha\u002Fdemote",[645,1355,1193],{},[645,1357,1358,1359,1346],{},"Demote a specific active (",[324,1360,1345],{},[421,1362,1364],{"className":536,"code":1363,"language":538,"meta":426,"style":426},"curl -s localhost:8080\u002Fha\u002Fstatus\ncurl -s -X POST localhost:8080\u002Fha\u002Fswitch\n# -> {\"command\":\"SWITCH\",\"target\":null,\"commandOffset\":42}\n",[324,1365,1366,1375,1388],{"__ignoreMap":426},[430,1367,1368,1370,1372],{"class":432,"line":433},[430,1369,546],{"class":545},[430,1371,550],{"class":549},[430,1373,1374],{"class":553}," localhost:8080\u002Fha\u002Fstatus\n",[430,1376,1377,1379,1381,1383,1385],{"class":432,"line":444},[430,1378,546],{"class":545},[430,1380,550],{"class":549},[430,1382,1226],{"class":549},[430,1384,1229],{"class":553},[430,1386,1387],{"class":553}," localhost:8080\u002Fha\u002Fswitch\n",[430,1389,1390],{"class":432,"line":452},[430,1391,1392],{"class":476},"# -> {\"command\":\"SWITCH\",\"target\":null,\"commandOffset\":42}\n",[320,1394,1395,1396,1399,1400,1403,1404,1407,1408,1411,1412,1414,1415,1417],{},"The write endpoints publish a command and return ",[324,1397,1398],{},"202 Accepted"," with the command's offset as an idempotency token; the targeted pod observes it and acts. If no caught-up (",[324,1401,1402],{},"READY_STANDBY",") target exists, they reject with ",[324,1405,1406],{},"409 Conflict"," — handing off to a not-ready peer is a self-inflicted outage; ",[324,1409,1410],{},"?force=true"," overrides the gate (a forced promotion still fully restores state before processing). See ",[403,1413,233],{"href":234}," for the operational guide and ",[403,1416,286],{"href":287}," for full response shapes.",[406,1419,1421],{"id":1420},"license","License",[621,1423,1424,1434],{},[624,1425,1426],{},[627,1427,1428,1430,1432],{},[630,1429,632],{},[630,1431,635],{},[630,1433,638],{},[640,1435,1436],{},[627,1437,1438,1442,1444],{},[645,1439,1440],{},[324,1441,565],{},[645,1443,358],{},[645,1445,1446],{},"Current runtime license-validation state.",[320,1448,1449,1451,1452,1454],{},[324,1450,565],{}," reports validation ",[324,1453,1121],{},", tier, expiry and days remaining, machine usage against the allowance, and heartbeat\u002Fgrace state.",[421,1456,1458],{"className":536,"code":1457,"language":538,"meta":426,"style":426},"curl -s localhost:8080\u002Flicense\n",[324,1459,1460],{"__ignoreMap":426},[430,1461,1462,1464,1466],{"class":432,"line":433},[430,1463,546],{"class":545},[430,1465,550],{"class":549},[430,1467,1468],{"class":553}," localhost:8080\u002Flicense\n",[556,1470,1471],{"color":558,"icon":559},[320,1472,1473,1474,570,1477,1480,1481,1483],{},"The response contains customer-identifying fields (",[324,1475,1476],{},"licenseId",[324,1478,1479],{},"customerName",", machine counts). Treat it as in-cluster only — never expose ",[324,1482,565],{}," through internet ingress.",[320,1485,1486,1487,349],{},"The same state also surfaces through the license health indicator (readiness goes DOWN on expired\u002Frevoked\u002Finvalid licenses) and as metrics. See ",[403,1488,23],{"href":24},[406,1490,195],{"id":1491},"metrics",[621,1493,1494,1504],{},[624,1495,1496],{},[627,1497,1498,1500,1502],{},[630,1499,632],{},[630,1501,635],{},[630,1503,638],{},[640,1505,1506],{},[627,1507,1508,1513,1515],{},[645,1509,1510],{},[324,1511,1512],{},"\u002Fmetrics",[645,1514,358],{},[645,1516,1517],{},"Prometheus text-exposition scrape of JVM and application metrics.",[421,1519,1521],{"className":536,"code":1520,"language":538,"meta":426,"style":426},"curl -s localhost:8080\u002Fmetrics\n",[324,1522,1523],{"__ignoreMap":426},[430,1524,1525,1527,1529],{"class":432,"line":433},[430,1526,546],{"class":545},[430,1528,550],{"class":549},[430,1530,1531],{"class":553}," localhost:8080\u002Fmetrics\n",[320,1533,1534,1535,1538,1539,1541,1542,1545,1546,349],{},"The endpoint serves the Prometheus text format (",[324,1536,1537],{},"text\u002Fplain; version=0.0.4","). It returns ",[324,1540,394],{}," if metrics are disabled (",[324,1543,1544],{},"runtime.metrics.enabled: false","). The full meter catalogue — commit, changelog, restoration, dispatch, and license meters — is in ",[403,1547,195],{"href":196},[406,1549,1551],{"id":1550},"debug","Debug",[320,1553,1554],{},"Two pull-only diagnostic snapshots for investigating a stalled or frozen commit pipeline.",[621,1556,1557,1567],{},[624,1558,1559],{},[627,1560,1561,1563,1565],{},[630,1562,632],{},[630,1564,635],{},[630,1566,638],{},[640,1568,1569,1581],{},[627,1570,1571,1576,1578],{},[645,1572,1573],{},[324,1574,1575],{},"\u002Fdebug\u002Fthreads",[645,1577,358],{},[645,1579,1580],{},"Snapshot of engine-owned and platform thread state and stacks, for freeze diagnosis.",[627,1582,1583,1588,1590],{},[645,1584,1585],{},[324,1586,1587],{},"\u002Fdebug\u002Fbarriers",[645,1589,358],{},[645,1591,1592,1593,1596],{},"Commit-pipeline snapshot: in-flight commit progress, which lanes are outstanding, and a derived ",[324,1594,1595],{},"phase"," summary.",[320,1598,1599,1600,1603,1604,1607,1608,1610],{},"Both are gated by ",[324,1601,1602],{},"runtime.http.debug.enabled"," (default ",[324,1605,1606],{},"true","). When disabled, they return ",[324,1609,1292],{},". They are snapshots of state already kept for other purposes, so there's no cost when nobody is calling them.",[421,1612,1614],{"className":536,"code":1613,"language":538,"meta":426,"style":426},"# Thread snapshot (optional: depth, filter=all|stuck|known)\ncurl -s 'localhost:8080\u002Fdebug\u002Fthreads?filter=stuck'\n\n# Commit-pipeline snapshot — see the derived phase\ncurl -s localhost:8080\u002Fdebug\u002Fbarriers\n",[324,1615,1616,1621,1635,1639,1644],{"__ignoreMap":426},[430,1617,1618],{"class":432,"line":433},[430,1619,1620],{"class":476},"# Thread snapshot (optional: depth, filter=all|stuck|known)\n",[430,1622,1623,1625,1627,1629,1632],{"class":432,"line":444},[430,1624,546],{"class":545},[430,1626,550],{"class":549},[430,1628,735],{"class":734},[430,1630,1631],{"class":553},"localhost:8080\u002Fdebug\u002Fthreads?filter=stuck",[430,1633,1634],{"class":734},"'\n",[430,1636,1637],{"class":432,"line":452},[430,1638,717],{"emptyLinePlaceholder":716},[430,1640,1641],{"class":432,"line":464},[430,1642,1643],{"class":476},"# Commit-pipeline snapshot — see the derived phase\n",[430,1645,1646,1648,1650],{"class":432,"line":480},[430,1647,546],{"class":545},[430,1649,550],{"class":549},[430,1651,1652],{"class":553}," localhost:8080\u002Fdebug\u002Fbarriers\n",[320,1654,1655,1657,1658,1661,1662,1665,1666,1669,1670,1673,1674,1677,1678,1680,1681,1683],{},[324,1656,1575],{}," accepts optional query params: ",[324,1659,1660],{},"depth"," (max stack frames per thread, default 40) and ",[324,1663,1664],{},"filter"," (",[324,1667,1668],{},"all"," default, ",[324,1671,1672],{},"stuck"," for non-runnable threads, ",[324,1675,1676],{},"known"," for engine threads only). ",[324,1679,1587],{}," summarises the commit pipeline into a single ",[324,1682,1595],{}," string so you can tell at a glance whether a commit is waiting on lanes, queued, in transaction, or idle.",[556,1685,1688],{"color":1686,"icon":1687},"info","i-lucide-info",[320,1689,1690,1691,349],{},"The debug endpoints expose internal engine state and are meant for diagnosis, not routine monitoring. Leave them on (they're free at rest), but keep them off public ingress. For hardened deployments that limit attack surface, set ",[324,1692,1693],{},"runtime.http.debug.enabled: false",[406,1695,1697],{"id":1696},"full-reference","Full reference",[320,1699,1700,1701,349],{},"This page is a tour by use case. For the exhaustive list — every response field, status code, and content-negotiation rule — see the ",[338,1702,1703],{},[403,1704,286],{"href":287},[1706,1707,1708],"style",{},"html pre.shiki code .su6XF, html code.shiki .su6XF{--shiki-default:#998418}html pre.shiki code .sYZai, html code.shiki .sYZai{--shiki-default:#999999}html pre.shiki code .sbBg2, html code.shiki .sbBg2{--shiki-default:#1E754F}html pre.shiki code .s-TwI, html code.shiki .s-TwI{--shiki-default:#2F798A}html pre.shiki code .s8zF2, html code.shiki .s8zF2{--shiki-default:#A0ADA0}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sySUi, html code.shiki .sySUi{--shiki-default:#59873A}html pre.shiki code .sEi1f, html code.shiki .sEi1f{--shiki-default:#A65E2B}html pre.shiki code .spphp, html code.shiki .spphp{--shiki-default:#B56959}html pre.shiki code .sSP4y, html code.shiki .sSP4y{--shiki-default:#B5695977}",{"title":426,"searchDepth":444,"depth":444,"links":1710},[1711,1712,1713,1714,1715,1716,1717,1718,1719,1720,1721],{"id":408,"depth":444,"text":409},{"id":615,"depth":444,"text":616},{"id":746,"depth":444,"text":747},{"id":905,"depth":444,"text":906},{"id":1066,"depth":444,"text":1067},{"id":1165,"depth":444,"text":1166},{"id":1278,"depth":444,"text":233},{"id":1420,"depth":444,"text":1421},{"id":1491,"depth":444,"text":195},{"id":1550,"depth":444,"text":1551},{"id":1696,"depth":444,"text":1697},"A task-oriented tour of the runtime's built-in HTTP endpoints — metadata, topology, state and progress, health, control, license, metrics, and debug.","md",{},{"icon":188},"how-to",{"title":185,"description":1722},"1Lv-zDtEw6s8iQr5iajnZKiylmKWg4mK8tQOOBGrf3M",[1730,1732],{"title":182,"path":178,"stem":179,"description":1731,"icon":183,"children":-1},"The batteries-included :runtime module — StoatFlowRuntime.fromConfig, the lifecycle (start \u002F awaitTermination \u002F stop), and what it adds over the bare :core engine.",{"title":190,"path":191,"stem":192,"description":1733,"icon":193,"children":-1},"Liveness and readiness probes on the StoatFlow runtime — the built-in indicators, what flips each, and how they behave during state restoration.",1783713361094]