> ## Documentation Index
> Fetch the complete documentation index at: https://docs.buttons.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# API buttons

> Wrap HTTP endpoints as pressable buttons with URL templates.

API buttons send an outbound HTTP request every time you press them. The URL, method, headers, and body are all stored in the button spec.

## Basic GET

```bash theme={null}
buttons create get-user \
  --url 'https://api.example.com/users/{{user_id}}' \
  --method GET \
  --arg user_id:string:required \
  -d "Fetch a user by ID"
```

Press it:

```bash theme={null}
buttons press get-user --arg user_id=42
```

The `{{user_id}}` placeholder in the URL path is replaced with the value you pass. Values in path segments are encoded with `PathEscape` to prevent injection.

## POST with a body

```bash theme={null}
buttons create create-issue \
  --url 'https://api.github.com/repos/{{owner}}/{{repo}}/issues' \
  --method POST \
  --header 'Authorization: Bearer {{token}}' \
  --header 'Content-Type: application/json' \
  --body '{"title": "{{title}}", "body": "{{description}}"}' \
  --arg owner:string:required \
  --arg repo:string:required \
  --arg token:string:required \
  --arg title:string:required \
  --arg description:string:optional \
  -d "Open a GitHub issue"
```

## Context-aware encoding

`{{arg}}` substitution is aware of where in the request the value appears:

| Location                                                      | Encoding applied   |
| ------------------------------------------------------------- | ------------------ |
| URL path segment                                              | `url.PathEscape`   |
| URL query parameter                                           | `url.QueryEscape`  |
| JSON body (`Content-Type: application/json`)                  | JSON string escape |
| Form body (`Content-Type: application/x-www-form-urlencoded`) | `url.QueryEscape`  |

This means a value like `O'Reilly & Sons` is safe to pass into a JSON body or a query string without manual escaping. See [template encoding](/security/template-encoding) for the full details.

## Custom headers

Pass `--header` once per header. Headers support `{{arg}}` substitution just like the URL and body:

```bash theme={null}
buttons create list-repos \
  --url 'https://api.github.com/users/{{username}}/repos' \
  --header 'Authorization: Bearer {{token}}' \
  --header 'Accept: application/vnd.github+json' \
  --arg username:string:required \
  --arg token:string:required
```

## Response size limit

Responses are capped at **10 MB** by default. Override with `--max-response-size` (value in bytes):

```bash theme={null}
buttons create large-export \
  --url 'https://api.example.com/export' \
  --max-response-size 52428800 \
  -d "Download up to 50 MB"
```

## Private network targets

By default, HTTP buttons block requests to private network ranges (loopback, RFC 1918, link-local). To allow a localhost or intranet target, pass `--allow-private-networks` at create time:

```bash theme={null}
buttons create local-health \
  --url 'http://127.0.0.1:8080/health' \
  --allow-private-networks \
  -d "Check local service health"
```

<Warning>
  Only use `--allow-private-networks` for buttons that target your own infrastructure. See [SSRF protection](/security/ssrf-protection) for the full threat model.
</Warning>

## Related

* [URL and body templates](/concepts/templates) — how `{{arg}}` substitution works
* [SSRF protection](/security/ssrf-protection) — private network blocking
* [Arguments](/concepts/arguments) — declare typed args
