{
  "components": {
    "schemas": {
      "Bindings": {
        "description": "Bindings names the primary binding and the base of each one offered.",
        "properties": {
          "http": {
            "$ref": "#/components/schemas/HTTPPrefix"
          },
          "primary": {
            "type": "string"
          }
        },
        "required": [
          "primary",
          "http"
        ],
        "type": "object"
      },
      "Build": {
        "description": "Build identifies the binary that answered: the version-control revision it was built from and whether that tree was dirty, from the binary's build information or from values stamped at link time, else \"unknown\" and true.",
        "properties": {
          "dirty": {
            "type": "boolean"
          },
          "go": {
            "type": "string"
          },
          "revision": {
            "type": "string"
          }
        },
        "required": [
          "revision",
          "dirty",
          "go"
        ],
        "type": "object"
      },
      "Check": {
        "description": "Check is one dependency the service needs in order to serve.",
        "properties": {
          "detail": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "status": {
            "description": "ok or failing",
            "type": "string"
          }
        },
        "required": [
          "name",
          "status",
          "detail"
        ],
        "type": "object"
      },
      "Describe": {
        "description": "Describe is the document /describe returns.",
        "properties": {
          "bindings": {
            "$ref": "#/components/schemas/Bindings"
          },
          "build": {
            "$ref": "#/components/schemas/Build"
          },
          "contract": {
            "type": "string"
          },
          "files": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "identity": {
            "type": "object"
          },
          "operations": {
            "items": {
              "$ref": "#/components/schemas/Operation"
            },
            "type": "array"
          },
          "refusals": {
            "items": {
              "$ref": "#/components/schemas/Refusal"
            },
            "type": "array"
          },
          "service": {
            "type": "string"
          }
        },
        "required": [
          "service",
          "contract",
          "build",
          "bindings",
          "operations",
          "refusals",
          "files"
        ],
        "title": "Describe",
        "type": "object"
      },
      "Error": {
        "description": "ErrorResponse is the JSON envelope of every refusal and protocol error.",
        "properties": {
          "error": {
            "type": "string"
          }
        },
        "required": [
          "error"
        ],
        "title": "Error",
        "type": "object"
      },
      "HTTPBinding": {
        "description": "HTTPBinding carries an operation as one request and one response.",
        "properties": {
          "method": {
            "type": "string"
          },
          "path": {
            "type": "string"
          }
        },
        "required": [
          "method",
          "path"
        ],
        "type": "object"
      },
      "HTTPPrefix": {
        "description": "HTTPPrefix is where the application routes of the HTTP binding live.",
        "properties": {
          "prefix": {
            "type": "string"
          }
        },
        "required": [
          "prefix"
        ],
        "type": "object"
      },
      "Health": {
        "description": "Health is the envelope of /livez and /healthz.",
        "properties": {
          "build": {
            "$ref": "#/components/schemas/Build"
          },
          "checks": {
            "items": {
              "$ref": "#/components/schemas/Check"
            },
            "type": "array"
          },
          "contract": {
            "type": "string"
          },
          "identity": {
            "type": "object"
          },
          "service": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "time": {
            "type": "string"
          }
        },
        "required": [
          "status",
          "service",
          "contract",
          "build",
          "time",
          "checks"
        ],
        "title": "Health",
        "type": "object"
      },
      "NamesRequest": {
        "description": "NamesRequest is the body of get many.",
        "properties": {
          "names": {
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "required": [
          "names"
        ],
        "title": "NamesRequest",
        "type": "object"
      },
      "Operation": {
        "description": "Operation is one row of api/operations.json.",
        "properties": {
          "doc": {
            "type": "string"
          },
          "errors": {
            "description": "refusals beyond bad_request",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "http": {
            "$ref": "#/components/schemas/HTTPBinding"
          },
          "kind": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "params": {
            "items": {
              "$ref": "#/components/schemas/Param"
            },
            "type": "array"
          },
          "request": {
            "description": "body type; \"bytes\" or \"records\" for raw bodies",
            "type": "string"
          },
          "response": {
            "description": "result type; \"bytes\" or \"records\" for raw bodies",
            "type": "string"
          }
        },
        "required": [
          "name",
          "kind",
          "doc",
          "params",
          "errors",
          "http"
        ],
        "type": "object"
      },
      "Param": {
        "description": "Param is one named input of an operation, outside its body.",
        "properties": {
          "doc": {
            "type": "string"
          },
          "kind": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "required": {
            "type": "boolean"
          }
        },
        "required": [
          "name",
          "kind",
          "required",
          "doc"
        ],
        "type": "object"
      },
      "PutManyItem": {
        "description": "PutManyItem is one entry of a put many response: a name and size, or an error for the item that refused alone.",
        "properties": {
          "error": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "size": {
            "type": "integer"
          }
        },
        "type": "object"
      },
      "PutManyResponse": {
        "description": "PutManyResponse answers put many, one entry per record in request order.",
        "properties": {
          "results": {
            "items": {
              "$ref": "#/components/schemas/PutManyItem"
            },
            "type": "array"
          }
        },
        "required": [
          "results"
        ],
        "title": "PutManyResponse",
        "type": "object"
      },
      "PutResponse": {
        "description": "PutResponse acknowledges put and put stream.",
        "properties": {
          "name": {
            "type": "string"
          },
          "size": {
            "type": "integer"
          }
        },
        "required": [
          "name",
          "size"
        ],
        "title": "PutResponse",
        "type": "object"
      },
      "Refusal": {
        "description": "Refusal is one row of the refusal table: a name the surface defines, the HTTP status the binding maps it to, and its meaning.",
        "properties": {
          "http": {
            "type": "integer"
          },
          "meaning": {
            "type": "string"
          },
          "name": {
            "type": "string"
          }
        },
        "required": [
          "name",
          "http",
          "meaning"
        ],
        "type": "object"
      },
      "StatRequest": {
        "description": "StatRequest and NamesRequest are the JSON bodies of /v1/stat and /v1/get.",
        "properties": {
          "names": {
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "required": [
          "names"
        ],
        "title": "StatRequest",
        "type": "object"
      },
      "StatResponse": {
        "description": "StatResponse answers has and size: an entry for every requested name that is here, none for one that is not.",
        "properties": {
          "sizes": {
            "additionalProperties": {
              "type": "integer"
            },
            "type": "object"
          }
        },
        "required": [
          "sizes"
        ],
        "title": "StatResponse",
        "type": "object"
      }
    }
  },
  "info": {
    "description": "Generated from bnbytes.Operations and the SDK's types (ulab-standard/API.md). The contract is SURFACE.md and HTTP.md: record framing, atomic commit at end of stream, per-item batch commit and short reads live there and not here. Verbs that share a route appear once, with every verb listed under x-ulab-verbs.",
    "title": "bytes",
    "version": "2026-09-10"
  },
  "openapi": "3.1.0",
  "paths": {
    "/describe": {
      "get": {
        "operationId": "describe",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Describe"
                }
              }
            },
            "description": "the result"
          }
        },
        "summary": "who this is, which contract, which build, which bindings, which operations, which refusals",
        "tags": [
          "operational"
        ],
        "x-ulab-verbs": [
          "describe"
        ]
      }
    },
    "/describe/{file}": {
      "get": {
        "operationId": "describe_file",
        "parameters": [
          {
            "description": "a name listed by describe.files",
            "in": "path",
            "name": "file",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "text/markdown or application/json, per file": {
                "schema": {
                  "format": "binary",
                  "type": "string"
                }
              }
            },
            "description": "the result"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "not_found"
          }
        },
        "summary": "one committed contract file, verbatim",
        "tags": [
          "operational"
        ],
        "x-ulab-verbs": [
          "describe_file"
        ]
      }
    },
    "/healthz": {
      "get": {
        "operationId": "healthz",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Health"
                }
              }
            },
            "description": "the result"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Health"
                }
              }
            },
            "description": "failing: the same envelope with the failing checks"
          }
        },
        "summary": "the service can serve its contract: every dependency check passes",
        "tags": [
          "operational"
        ],
        "x-ulab-verbs": [
          "healthz"
        ]
      }
    },
    "/livez": {
      "get": {
        "operationId": "livez",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Health"
                }
              }
            },
            "description": "the result"
          }
        },
        "summary": "the process is up and can answer",
        "tags": [
          "operational"
        ],
        "x-ulab-verbs": [
          "livez"
        ]
      }
    },
    "/v1/blobs": {
      "post": {
        "operationId": "put",
        "requestBody": {
          "content": {
            "application/octet-stream": {
              "schema": {
                "format": "binary",
                "type": "string"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PutResponse"
                }
              }
            },
            "description": "the result"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "bad_request"
          },
          "413": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "too_large"
          }
        },
        "summary": "store bytes under their hash; idempotent",
        "tags": [
          "mutation"
        ],
        "x-ulab-verbs": [
          "put",
          "put_stream"
        ]
      }
    },
    "/v1/blobs/{name}": {
      "get": {
        "operationId": "get",
        "parameters": [
          {
            "description": "sha256:\u003c64 lowercase hex\u003e",
            "in": "path",
            "name": "name",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "first byte, default 0",
            "in": "query",
            "name": "offset",
            "required": false,
            "schema": {
              "minimum": 0,
              "type": "integer"
            }
          },
          {
            "description": "byte count, default to the end",
            "in": "query",
            "name": "length",
            "required": false,
            "schema": {
              "minimum": 0,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/octet-stream": {
                "schema": {
                  "format": "binary",
                  "type": "string"
                }
              }
            },
            "description": "the result"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "bad_request"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "not_found"
          }
        },
        "summary": "the bytes of one blob",
        "tags": [
          "read"
        ],
        "x-ulab-verbs": [
          "get",
          "get_range",
          "get_stream"
        ]
      }
    },
    "/v1/get": {
      "post": {
        "operationId": "get_many",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NamesRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/x-bn-blobs": {
                "schema": {
                  "format": "binary",
                  "type": "string"
                }
              }
            },
            "description": "the result"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "bad_request"
          }
        },
        "summary": "the blobs that are here among the names, as records keyed by name, unordered",
        "tags": [
          "read"
        ],
        "x-ulab-verbs": [
          "get_many"
        ]
      }
    },
    "/v1/put": {
      "post": {
        "operationId": "put_many",
        "requestBody": {
          "content": {
            "application/x-bn-blobs": {
              "schema": {
                "format": "binary",
                "type": "string"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PutManyResponse"
                }
              }
            },
            "description": "the result"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "bad_request"
          }
        },
        "summary": "store each anonymous record independently; results in request order",
        "tags": [
          "mutation"
        ],
        "x-ulab-verbs": [
          "put_many"
        ]
      }
    },
    "/v1/stat": {
      "post": {
        "operationId": "has",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/StatRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StatResponse"
                }
              }
            },
            "description": "the result"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "bad_request"
          }
        },
        "summary": "which of the names are here: presence of a key in sizes",
        "tags": [
          "read"
        ],
        "x-ulab-verbs": [
          "has",
          "size"
        ]
      }
    }
  },
  "servers": [
    {
      "description": "the standalone default listener",
      "url": "http://127.0.0.1:8080"
    }
  ]
}
