Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion docs/reference/kubo/rpc.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ I AM SERIOUS, DO NOT EDIT ANYTHING BELOW ;-D

-->

::: tip Generated on 2026-03-10, from kubo v0.40.1
::: tip Generated on 2026-03-17, from kubo v0.40.1
This document was autogenerated from [v0.40.1](https://github.com/ipfs/kubo/releases/tag/v0.40.1).
For issues and support, check out the [http-api-docs](https://github.com/ipfs/ipfs-docs/tree/main/tools/http-api-docs) generator on GitHub.
:::
Expand Down Expand Up @@ -157,6 +157,24 @@ A `405` error may mean that you are using the wrong HTTP method (i.e. GET instea
When a request is sent from a browser, HTTP RPC API follows the [Origin-based security model](https://en.wikipedia.org/wiki/Same-origin_policy), and expects the `Origin` HTTP header to be present.
The API will return HTTP Error 403 when Origin is missing, does not match the API port, or is not safelisted via `API.HTTPHeaders.Access-Control-Allow-Origin` in the config.

## Global options

The following options apply to all endpoints and can be passed as query parameters on every request.
These correspond to global flags on the `ipfs` CLI (e.g. `--offline`, `--cid-base`, `--timeout`).

- `offline` [bool]: Run the command offline. Required: no.
- `cid-base` [string]: Multibase encoding for CIDs in output. CIDv0 is automatically converted to CIDv1 when a base other than base58btc is specified. Required: no.
- `timeout` [string]: Set a global timeout on the command. Required: no.

### Authentication

The `--api-auth` option is used for [RPC API authorization](https://github.com/ipfs/kubo/blob/master/docs/config.md#apiauthorizations).
Unlike the query parameter options above, it must be sent as an HTTP header:

```
Authorization: Bearer <secret>
```


## RPC commands

Expand Down
64 changes: 64 additions & 0 deletions tools/http-api-docs/endpoints.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,70 @@ func IPFSVersion() string {
return config.CurrentVersionNumber
}

// ignoredGlobalOptions lists root-level flags that should not appear in the
// HTTP RPC API reference. This includes:
// - CLI-only flags (--repo-dir, --config-file, --api, --debug, --help)
// that refer to local paths or control CLI behavior
// - --encoding: the HTTP handler defaults to JSON and this is already
// documented in the "Flags" intro section of the reference
// - --stream-channels: parsed by the HTTP handler but has no effect;
// HTTP response streaming is determined by the response type, not this flag
// - --upgrade-cidv0-in-output: deprecated, --cid-base with a non-base58btc
// value now automatically upgrades CIDv0 to CIDv1
var ignoredGlobalOptions = map[string]struct{}{
corecmds.RepoDirOption: {},
corecmds.ConfigFileOption: {},
corecmds.ConfigOption: {},
corecmds.DebugOption: {},
corecmds.LocalOption: {}, // deprecated alias for --offline
corecmds.ApiOption: {},
"help": {}, // cmds.OptLongHelp
"h": {}, // cmds.OptShortHelp
cmds.EncLong: {}, // --encoding: HTTP defaults to JSON, documented in intro
cmds.ChanOpt: {}, // --stream-channels: no-op over HTTP
"upgrade-cidv0-in-output": {}, // deprecated: --cid-base auto-upgrades for non-base58btc
}

// GlobalOptions extracts the options defined on corecmds.Root that are
// relevant to the HTTP RPC API. The Root command itself has Run == nil so
// Endpoints() skips it, but its Options slice contains global flags
// (--offline, --timeout, --cid-base, etc.) that can be passed as query
// parameters to any endpoint. Flags listed in ignoredGlobalOptions are
// filtered out.
//
// The --api-auth flag is a special case: it controls RPC authentication
// but is sent as an HTTP Authorization header, not a query parameter.
// It is returned separately so the formatter can document it differently.
func GlobalOptions() (queryOpts []*Argument, authOpt *Argument) {
for _, opt := range corecmds.Root.Options {
name := opt.Names()[0]
if _, skip := ignoredGlobalOptions[name]; skip {
continue
}

def := fmt.Sprint(opt.Default())
if def == "<nil>" {
def = ""
}

arg := &Argument{
Name: name,
Type: opt.Type().String(),
Description: opt.Description(),
Default: def,
}

// api-auth is sent as an HTTP header, not a query parameter
if name == corecmds.ApiAuthOption {
authOpt = arg
continue
}

queryOpts = append(queryOpts, arg)
}
return queryOpts, authOpt
}

// Endpoints receives a name and a go-ipfs command and returns the endpoints it
// defines] (sorted). It does this by recursively gathering endpoints defined by
// subcommands. Thus, calling it with the core command Root generates all
Expand Down
52 changes: 51 additions & 1 deletion tools/http-api-docs/endpoints_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,57 @@
package docs

import "testing"
import (
"slices"
"testing"
)

func TestEndpoints(t *testing.T) {
AllEndpoints()
}

func TestGlobalOptions(t *testing.T) {
queryOpts, authOpt := GlobalOptions()

// Verify we got some query parameter options
if len(queryOpts) == 0 {
t.Fatal("expected at least one global query parameter option")
}

// Collect names for easier assertions
names := make([]string, len(queryOpts))
for i, opt := range queryOpts {
names[i] = opt.Name
}

// Key RPC-relevant flags should be present
for _, expected := range []string{"offline", "cid-base", "timeout"} {
if !slices.Contains(names, expected) {
t.Errorf("expected global option %q not found in %v", expected, names)
}
}

// Ignored flags should be filtered out: CLI-only flags, plus encoding
// (HTTP defaults to JSON, documented in intro), stream-channels
// (no-op over HTTP), and upgrade-cidv0-in-output (deprecated).
for _, excluded := range []string{
"repo-dir", "config-file", "config", "debug", "local", "api", "help", "h",
"encoding", "stream-channels", "upgrade-cidv0-in-output",
} {
if slices.Contains(names, excluded) {
t.Errorf("ignored option %q should not appear in global RPC options", excluded)
}
}

// api-auth should be returned as the separate auth option
if authOpt == nil {
t.Fatal("expected api-auth to be returned as authOpt")
}
if authOpt.Name != "api-auth" {
t.Errorf("expected authOpt.Name == \"api-auth\", got %q", authOpt.Name)
}

// api-auth should not appear in the query parameter list
if slices.Contains(names, "api-auth") {
t.Error("api-auth should not appear in query parameter options")
}
}
15 changes: 14 additions & 1 deletion tools/http-api-docs/formatter.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ import (
// Formatter allows to implement generation of docs in different formats.
type Formatter interface {
GenerateIntro() string
// GenerateGlobalOptionsBlock documents global options that apply to all
// endpoints. queryOpts are passed as URL query parameters; authOpt (if
// non-nil) is the authentication option sent via HTTP header instead.
GenerateGlobalOptionsBlock(queryOpts []*Argument, authOpt *Argument) string
GenerateStatusIntro(status cmds.Status) string
GenerateIndex(endp []*Endpoint) string
GenerateEndpointBlock(endp *Endpoint) string
Expand All @@ -18,11 +22,20 @@ type Formatter interface {
GenerateExampleBlock(endp *Endpoint) string
}

// GenerateDocs uses a formatter to generate documentation for every endpoint
// GenerateDocs uses a formatter to generate documentation for every endpoint.
// It first emits the intro and global options sections, then iterates through
// endpoints grouped by status (active, experimental, deprecated, removed).
func GenerateDocs(api []*Endpoint, formatter Formatter) string {
buf := new(bytes.Buffer)
buf.WriteString(formatter.GenerateIntro())

// Document global options from the root command before per-endpoint docs.
// These are flags like --offline, --timeout, --encoding that apply to
// every RPC endpoint but were previously missing from the reference.
// See https://github.com/ipfs/ipfs-docs/issues/1084
queryOpts, authOpt := GlobalOptions()
buf.WriteString(formatter.GenerateGlobalOptionsBlock(queryOpts, authOpt))

for _, status := range []cmds.Status{cmds.Active, cmds.Experimental, cmds.Deprecated, cmds.Removed} {
endpoints := InStatus(api, status)
if len(endpoints) == 0 {
Expand Down
39 changes: 39 additions & 0 deletions tools/http-api-docs/markdown.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,45 @@ The API will return HTTP Error 403 when Origin is missing, does not match the AP
return buf.String()
}

// GenerateGlobalOptionsBlock produces a markdown section documenting global
// options that apply to every RPC endpoint. These are defined on Kubo's root
// command but were previously omitted because the root command has no handler
// of its own (Run == nil). Query parameter options (--offline, --timeout, etc.)
// are listed as a standard arguments block. The --api-auth option is documented
// separately since it is sent as an HTTP Authorization header, not a query param.
func (md *MarkdownFormatter) GenerateGlobalOptionsBlock(queryOpts []*Argument, authOpt *Argument) string {
buf := new(bytes.Buffer)

fmt.Fprint(buf, `## Global options

The following options apply to all endpoints and can be passed as query parameters on every request.
These correspond to global flags on the `+"`ipfs`"+` CLI (e.g. `+"`--offline`"+`, `+"`--cid-base`"+`, `+"`--timeout`"+`).

`)

for _, opt := range queryOpts {
fmt.Fprint(buf, genArgument(opt, false))
}

// Document the api-auth option separately: it is relevant to the RPC API
// but travels as an HTTP header rather than a URL query parameter.
if authOpt != nil {
fmt.Fprintf(buf, `
### Authentication

The `+"`--%s`"+` option is used for [RPC API authorization](https://github.com/ipfs/kubo/blob/master/docs/config.md#apiauthorizations).
Unlike the query parameter options above, it must be sent as an HTTP header:

`+"```"+`
Authorization: Bearer <secret>
`+"```"+`

`, authOpt.Name)
}

return buf.String()
}

func (md *MarkdownFormatter) GenerateStatusIntro(status cmds.Status) string {
return fmt.Sprintf(`
## %s RPC commands
Expand Down
Loading