1"use strict";(self.webpackChunkmeshtastic=self.webpackChunkmeshtastic||[]).push([["22425"],{56100(e,t,i){i.r(t),i.d(t,{metadata:()=>n,default:()=>u,frontMatter:()=>d,contentTitle:()=>l,toc:()=>c,assets:()=>a});var n=JSON.parse('{"id":"development/device/http-api","title":"HTTP API","description":"This is a mini-spec on a HTTP API which can be used by browser based clients to interact with Meshtastic devices.","source":"@site/docs/development/device/http-api.mdx","sourceDirName":"development/device","slug":"/development/device/http-api","permalink":"/docs/development/device/http-api","draft":false,"unlisted":false,"editUrl":"https://github.com/meshtastic/meshtastic/edit/master/docs/development/device/http-api.mdx","tags":[],"version":"current","lastUpdatedBy":"rcarteraz","sidebarPosition":2,"frontMatter":{"id":"http-api","title":"HTTP API","sidebar_label":"HTTP API","sidebar_position":2},"sidebar":"Sidebar","previous":{"title":"Client API","permalink":"/docs/development/device/client-api"},"next":{"title":"Module API","permalink":"/docs/development/device/module-api"}}'),o=i(91987),s=i(67008),r=i(87622);let d={id:"http-api",title:"HTTP API",sidebar_label:"HTTP API",sidebar_position:2},l,a={},c=[{value:"Why protobufs",id:"why-protobufs",level:2},{value:"Request headers",id:"request-headers",level:2},{value:"Response headers",id:"response-headers",level:2},{value:"Endpoints",id:"endpoints",level:2},{value:"/api/v1/toradio",id:"apiv1toradio",level:3},{value:"PUT",id:"put",level:4},{value:"OPTIONS",id:"options",level:4},{value:"/api/v1/fromradio",id:"apiv1fromradio",level:3},{value:"GET",id:"get",level:4},{value:"<strong>/api/v1/fromradio?all</strong>",id:"apiv1fromradioall",level:5},{value:"<strong>/api/v1/fromradio?chunked</strong>",id:"apiv1fromradiochunked",level:5},{value:"Authentication",id:"authentication",level:2},{value:"Client",id:"client",level:2},{value:"JavaScript",id:"javascript",level:3},{value:"Protoman",id:"protoman",level:3},{value:"Security",id:"security",level:2},{value:"Related documents",id:"related-documents",level:2}];function h(e){let t={a:"a",admonition:"admonition",code:"code",h2:"h2",h3:"h3",h4:"h4",h5:"h5",li:"li",p:"p",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.admonition,{type:"info",children:(0,o.jsx)(t.p,{children:"This is a mini-spec on a HTTP API which can be used by browser based clients to interact with Meshtastic devices."})}),"\n",(0,o.jsx)(t.h2,{id:"why-protobufs",children:"Why protobufs"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsx)(t.li,{children:"No need for JSON parsing on the resource constrained embedded server."}),"\n",(0,o.jsx)(t.li,{children:"Small."}),"\n",(0,o.jsx)(t.li,{children:"Already in use for all other transports (so shared testing/tooling coverage)."}),"\n",(0,o.jsx)(t.li,{children:"Backwards and forward compatible."}),"\n"]}),"\n",(0,o.jsx)(t.h2,{id:"request-headers",children:"Request headers"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.code,{children:"Content-Type: application/x-protobuf"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsxs)(t.li,{children:["Indicates ",(0,o.jsx)(r.A,{term:"Protobuf",definition:"A method developed by Google for serializing structured data, used in Meshtastic for efficient communication protocol between devices.",routePath:"/docs/terms/",children:"protobuf"})," content (Meshtastic ",(0,o.jsx)(r.A,{term:"Protobuf",definition:"A method developed by Google for serializing structured data, used in Meshtastic for efficient communication protocol between devices.",routePath:"/docs/terms/",children:"protobufs"}),")"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(t.h2,{id:"response-headers",children:"Response headers"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.code,{children:"Content-Type: application/x-protobuf"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsxs)(t.li,{children:["Indicates ",(0,o.jsx)(r.A,{term:"Protobuf",definition:"A method developed by Google for serializing structured data, used in Meshtastic for efficient communication protocol between devices.",routePath:"/docs/terms/",children:"protobuf"})," content (Meshtastic ",(0,o.jsx)(r.A,{term:"Protobuf",definition:"A method developed by Google for serializing structured data, used in Meshtastic for efficient communication protocol between devices.",routePath:"/docs/terms/",children:"protobufs"}),")"]}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.code,{children:"X-Protobuf-Schema: <URI to the .proto schema file>"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsx)(t.li,{children:"Not required but recommended for documentation/reflection purposes"}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(t.h2,{id:"endpoints",children:"Endpoints"}),"\n",(0,o.jsx)(t.p,{children:"Two endpoints are specified:"}),"\n",(0,o.jsx)(t.h3,{id:"apiv1toradio",children:"/api/v1/toradio"}),"\n",(0,o.jsxs)(t.p,{children:["Allows ",(0,o.jsx)(t.code,{children:"PUT"})," and ",(0,o.jsx)(t.code,{children:"OPTION"})," requests."]}),"\n",(0,o.jsx)(t.h4,{id:"put",children:"PUT"}),"\n",(0,o.jsxs)(t.p,{children:["A ",(0,o.jsx)(t.code,{children:"PUT"})," request to this endpoint will be expected to contain a series of ToRadio ",(0,o.jsx)(r.A,{term:"Protobuf",definition:"A method developed by Google for serializing structured data, used in Meshtastic for efficient communication protocol between devices.",routePath:"/docs/terms/",children:"protobuf"})," payloads."]}),"\n",(0,o.jsxs)(t.p,{children:["The ",(0,o.jsx)(r.A,{term:"Protobuf",definition:"A method developed by Google for serializing structured data, used in Meshtastic for efficient communication protocol between devices.",routePath:"/docs/terms/",children:"protobufs"})," will be sent in binary as the body for the request."]}),"\n",(0,o.jsx)(t.p,{children:"Only one ToRadio message per request is supported."}),"\n",(0,o.jsx)(t.h4,{id:"options",children:"OPTIONS"}),"\n",(0,o.jsxs)(t.p,{children:["An ",(0,o.jsx)(t.code,{children:"OPTIONS"}),"request to this endpoint will return a response status code ",(0,o.jsx)(t.code,{children:"204"})," and headers only."]}),"\n",(0,o.jsx)(t.h3,{id:"apiv1fromradio",children:"/api/v1/fromradio"}),"\n",(0,o.jsxs)(t.p,{children:["Allows ",(0,o.jsx)(t.code,{children:"GET"})," requests."]}),"\n",(0,o.jsx)(t.h4,{id:"get",children:"GET"}),"\n",(0,o.jsxs)(t.p,{children:["A ",(0,o.jsx)(t.code,{children:"GET"})," request from this endpoint will return a series of FromRadio ",(0,o.jsx)(r.A,{term:"Protobuf",definition:"A method developed by Google for serializing structured data, used in Meshtastic for efficient communication protocol between devices.",routePath:"/docs/terms/",children:"protobufs"}),"."]}),"\n",(0,o.jsxs)(t.p,{children:["The ",(0,o.jsx)(r.A,{term:"Protobuf",definition:"A method developed by Google for serializing structured data, used in Meshtastic for efficient communication protocol between devices.",routePath:"/docs/terms/",children:"protobufs"})," will be sent in binary as the body for the request."]}),"\n",(0,o.jsx)(t.p,{children:(0,o.jsx)(t.strong,{children:"Parameters"})}),"\n",(0,o.jsx)(t.h5,{id:"apiv1fromradioall",children:(0,o.jsx)(t.strong,{children:"/api/v1/fromradio?all"})}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.code,{children:"all=false"})," (unset default)","\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsxs)(t.li,{children:["Only one ",(0,o.jsx)(r.A,{term:"Protobuf",definition:"A method developed by Google for serializing structured data, used in Meshtastic for efficient communication protocol between devices.",routePath:"/docs/terms/",children:"protobuf"})," is returned."]}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.code,{children:"all=true"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsxs)(t.li,{children:["All available ",(0,o.jsx)(r.A,{term:"Protobuf",definition:"A method developed by Google for serializing structured data, used in Meshtastic for efficient communication protocol between devices.",routePath:"/docs/terms/",children:"protobufs"})," are returned."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(t.h5,{id:"apiv1fromradiochunked",children:(0,o.jsx)(t.strong,{children:"/api/v1/fromradio?chunked"})}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.code,{children:"chunked=false"})," (unset default, not yet implemented)","\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsxs)(t.li,{children:["The request returns all ",(0,o.jsx)(r.A,{term:"Protobuf",definition:"A method developed by Google for serializing structured data, used in Meshtastic for efficient communication protocol between devices.",routePath:"/docs/terms/",children:"protobufs"})," that can be delivered for the client's session (this would allow the client to poll by doing a series of requests). This is the only option that is supported in the initial release."]}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.code,{children:"chunked=true"})," (not yet implemented)","\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsxs)(t.li,{children:["If chunked=true, the response will be a ",(0,o.jsx)(t.a,{href:"https://en.wikipedia.org/wiki/Chunked_transfer_encoding",children:"stream of chunks"})," that the server will keep open as long as the client wants. This will allow efficie
1nt streaming of new ",(0,o.jsx)(t.code,{children:"FromRadio"})," ",(0,o.jsx)(r.A,{term:"Protobuf",definition:"A method developed by Google for serializing structured data, used in Meshtastic for efficient communication protocol between devices.",routePath:"/docs/terms/",children:"protobufs"})," as they are generated by the radio."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(t.h2,{id:"authentication",children:"Authentication"}),"\n",(0,o.jsxs)(t.p,{children:["There isn't ",(0,o.jsx)(t.strong,{children:"any"})," user authentication. We assume access to the HTTP server is enough to establish trust."]}),"\n",(0,o.jsx)(t.h2,{id:"client",children:"Client"}),"\n",(0,o.jsx)(t.h3,{id:"javascript",children:"JavaScript"}),"\n",(0,o.jsxs)(t.p,{children:["See: ",(0,o.jsx)(t.a,{href:"https://github.com/meshtastic/meshtastic.js",children:"https://github.com/meshtastic/meshtastic.js"})]}),"\n",(0,o.jsxs)(t.p,{children:["A reference client written in JavaScript will provide a JavaScript API for using this transport. That client will do HTTP connections, use the generated ",(0,o.jsx)(r.A,{term:"Protobuf",definition:"A method developed by Google for serializing structured data, used in Meshtastic for efficient communication protocol between devices.",routePath:"/docs/terms/",children:"protobuf"})," JavaScript code and provide an API that hides all of this REST plumbing. The two key methods will be ",(0,o.jsx)(t.code,{children:"sendToRadio(packet)"})," and ",(0,o.jsx)(t.code,{children:"onFromRadio(callback)"}),"."]}),"\n",(0,o.jsx)(t.h3,{id:"protoman",children:"Protoman"}),"\n",(0,o.jsxs)(t.p,{children:["See: ",(0,o.jsx)(t.a,{href:"https://github.com/spluxx/Protoman",children:"https://github.com/spluxx/Protoman"})]}),"\n",(0,o.jsx)(t.p,{children:"Protoman is able to interface with the Meshtastic REST API out of the box. This is useful for manual testing of the endpoints."}),"\n",(0,o.jsx)(t.h2,{id:"security",children:"Security"}),"\n",(0,o.jsxs)(t.p,{children:["HTTP and HTTPS are both supported on the ",(0,o.jsx)(r.A,{term:"ESP32",definition:"A chipset of microcontroller made/designed by Espressif, used by a number of devices. Higher power usage than nRF52, but often cheaper and supports Wi-Fi if desired.",routePath:"/docs/terms/",children:"ESP32"})," using self-signed certificates on HTTPS."]}),"\n",(0,o.jsx)(t.h2,{id:"related-documents",children:"Related documents"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsxs)(t.li,{children:["Interesting slide pack on the concept: ",(0,o.jsx)(t.a,{href:"https://www.slideshare.net/mokeefe/javaone-2009-ts5276-restful-protocol-buffers",children:"https://www.slideshare.net/mokeefe/javaone-2009-ts5276-restful-protocol-buffers"})]}),"\n"]})]})}function u(e={}){let{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(h,{...e})}):h(e)}},67008(e,t,i){i.d(t,{R:()=>r,x:()=>d});var n=i(71763);let o={},s=n.createContext(o);function r(e){let t=n.useContext(s);return n.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function d(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),n.createElement(s.Provider,{value:t},e.children)}},87622(e,t,i){i.d(t,{A:()=>r});var n=i(71763),o=i(37773),s=i(91987);function r({term:e,definition:t,abbreviation:i,routePath:d="/glossary",children:l}
1){let[a,c]=(0,n.useState)(!1),[h,u]=(0,n.useState)(null),[p,f]=(0,n.useState)("top"),m=(0,n.useRef)(null),x=(0,n.useRef)(null),v=(0,n.useCallback)(()=>{let e;if(!m.current||!x.current)return;let t=m.current.getBoundingClientRect(),i=x.current.getBoundingClientRect(),n=window.innerWidth,o=window.innerHeight,s=document.querySelector(".navbar"),r=s?s.getBoundingClientRect().bottom:0,d=t.top-r>=i.height+8,l=o-t.bottom>=i.height+8,a=d||!l?"top":"bottom";e="top"===a?t.top-i.height-8:t.bottom+8;let c=t.left+t.width/2-i.width/2;c=Math.max(8,Math.min(c,n-i.width-8)),f(a),u({top:Math.max(r+4,e),left:c})},[]);(0,n.useEffect)(()=>{let e;if(!a)return;let t=requestAnimationFrame(()=>{e=requestAnimationFrame(()=>{v()})}),i=()=>v(),n=()=>v();return window.addEventListener("scroll",i,!0),window.addEventListener("resize",n),()=>{cancelAnimationFrame(t),e&&cancelAnimationFrame(e),window.removeEventListener("scroll",i,!0),window.removeEventListener("resize",n)}},[a,v]);let b=(0,o.P_)("docusaurus-plugin-glossary"),j=(0,n.useMemo)(()=>{if(t&&"string"==typeof t&&t.length>0)return t;let i=(b&&b.terms||[]).find(t=>"string"==typeof t.term&&t.term.toLowerCase()===String(e).toLowerCase());return i&&i.definition?i.definition:void 0},[t,b,e]),g=(0,n.useMemo)(()=>{let t=i;if(!t){let i=(b&&b.terms||[]).find(t=>"string"==typeof t.term&&t.term.toLowerCase()===String(e).toLowerCase());t=i&&i.abbreviation}if("string"!=typeof t)return;let n=t.trim();if(n&&n.toLowerCase()!==String(e).toLowerCase())return n},[i,b,e]),w=(0,n.useMemo)(()=>d&&"string"==typeof d&&d.length>0?d:b&&b.routePath||"/glossary",[b,d]),P=l||e,y=e.toLowerCase().replace(/\s+/g,"-");return(0,s.jsxs)("span",{ref:m,className:"glossaryTermWrapper_ud7W",children:[(0,s.jsx)("a",{href:`${w}#${y}`,className:"glossaryTerm_x2nJ",onMouseEnter:()=>c(!0),onMouseLeave:()=>c(!1),onFocus:()=>c(!0),onBlur:()=>c(!1),"aria-describedby":`tooltip-${y}`,children:P}),j&&(0,s.jsxs)("span",{ref:x,id:`tooltip-${y}`,className:`tooltip_WjgA ${a?"tooltipVisible_AjfD":""} ${"top"===p?"tooltipTop_uMN4":"tooltipBottom_U9P5"} tooltipFloating_nLk7`,role:"tooltip",style:a&&h?{top:`${h.top}px`,left:`${h.left}px`}:void 0,children:[(0,s.jsx)("strong",{children:e}),g?` (${g}). `:"",j]})]})}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.