> For the complete documentation index, see [llms.txt](https://docs.bosonnetwork.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.bosonnetwork.io/build-applications/http-rest.md).

# HTTP / REST Integration

Boson's HTTP APIs let you build on the network from any language - Python, TypeScript, Go, a shell script - without the Java SDK. This page walks through the integration once, end to end, against **Web Gateway**, the service that exposes the DHT over HTTPS. Every endpoint is specified in the [HTTP API reference](/reference/http-api.md).

{% hint style="info" %}
Building a **browser** application? A JavaScript light-node SDK is planned. Until it ships, call these endpoints with `fetch()`: Web Gateway accepts cross-origin requests. See [Node Types](/core-concepts/node-types.md) for every client option.
{% endhint %}

***

## What you need

1. **An account on a super node.** Web Gateway serves the users of the super node it runs on. Create the account with a Boson app, or through the [Director Client API](/reference/http-api/director-client.md#accounts).
2. **The user's Ed25519 key pair**, or a registered device's key pair, to sign tokens.
3. **The gateway's endpoint and peer id.**

***

## Step 1 - Find the gateway

Ask the super node which services it runs:

```bash
curl -s https://node.example.com/api/v1/client/node
```

```json
{
  "nodeId": "FyHfVWtscJWUeejGQaJXyUnjUcKFGSVVYmozqBuJSmjo",
  "running": true,
  "services": [
    {
      "serviceId": "io.bosonnetwork.webgateway",
      "peerId": "GbRwG3WgKgApSDBr9FGo5Y3RssSWxfWhanXMBdPCo5F2",
      "endpoint": "https://node.example.com/gateway"
    }
  ]
}
```

Your base URL is the `endpoint` followed by `/v1`, here `https://node.example.com/gateway/v1`. Keep the `peerId`: it is the audience of every token you send.

On a personal super node the endpoint looks like `https://203.0.113.10:9001`, and the certificate is self-signed; add `-k` to the `curl` commands below while experimenting.

***

## Step 2 - Issue a token

Every Web Gateway request, including the informational ones, carries a CBOR Web Token that **you issue yourself**, signed with the user's (or device's) key:

```http
Authorization: Bearer <token>
```

| Claim        | Key  | Value                                                    |
| ------------ | ---- | -------------------------------------------------------- |
| `iss`        | 1    | Your user id, or your device id when signing as a device |
| `sub`        | 2    | Your user id                                             |
| `aud`        | 3    | **The gateway's peer id**                                |
| `exp`        | 4    | A few minutes from now                                   |
| `nbf`, `iat` | 5, 6 | Now                                                      |
| `scope`      | 9    | `"client"`                                               |
| `client_id`  | 12   | Your device id, when signing as a device                 |

Ids are 32-byte binary strings in CBOR. Encode the claims as a COSE\_Sign1 structure with algorithm `EdDSA` (`-8`), sign with Ed25519, and base64url-encode the result. [Identity & CWT Format](/reference/identity-cwt-format.md) has the exact layout. Most COSE libraries can produce it.

Renew the token before it expires rather than issuing one per request. A token from the Director's `POST /api/v1/client/auth` will **not** work here: its audience is the super node, not the gateway.

***

## Step 3 - Make your first request

```bash
BASE=https://node.example.com/gateway/v1

curl -s -H "Authorization: Bearer $TOKEN" "$BASE/info"
```

```json
{ "nodeId": "FyHfVWts...", "peerId": "GbRwG3Wg...", "version": "<version>" }
```

A `401` means the token is wrong: check `aud`, the expiry, and that the user exists on this super node.

***

## Step 4 - Store and find a value

DHT records use compact JSON keys, with ids in Base58 and binary data in base64url without padding. An **immutable** value is just its data; its id is the SHA-256 hash of that data:

```bash
curl -s -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"value": {"v": "SGVsbG8gQm9zb24"}}' \
  "$BASE/values"
```

The response is `201 Created` with an **announce result** that says which DHT nodes stored it:

```json
{
  "targets": [
    { "id": "4ywCHfUY...", "outcome": "acknowledged" },
    { "id": "9ZC7mX2T...", "outcome": "timed_out" }
  ]
}
```

Look it up by its id:

```bash
curl -s -H "Authorization: Bearer $TOKEN" "$BASE/values/<value id>?mode=OPTIMISTIC"
```

```json
{ "v": "SGVsbG8gQm9zb24" }
```

A **mutable** value also carries its owner's public key `k`, a nonce `n`, a sequence number `seq` and a signature `sig`; you sign it before storing, and publish updates with a higher `seq`. See [Data Types](/reference/data-types.md#value) for the fields and what is signed.

***

## Step 5 - Announce and discover a service

A **peer** announces where a service can be reached. Sign a peer record and announce it:

```bash
curl -s -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"peer": {"id": "<peer id>", "sig": "<signature>", "f": 1, "e": "https://myservice.example.com"}}' \
  "$BASE/peers"
```

Anyone can then find it by its peer id:

```bash
curl -s -H "Authorization: Bearer $TOKEN" "$BASE/peers/<peer id>?count=4"
```

***

## Keep records alive while you are offline

DHT records expire. Add `"persistent": true` to a store or announce, and the gateway keeps the record and re-announces it for you, within the limits of your plan:

```json
{ "value": { ... }, "persistent": true }
```

List what the gateway holds for you with `GET /v1/user/values` and `GET /v1/user/peers`, and stop persisting a record with `DELETE`. See [Persistent values and peers](/reference/http-api/web-gateway.md#persistent-values-and-peers).

***

## Handling errors and limits

| Status | What to do                                                                     |
| ------ | ------------------------------------------------------------------------------ |
| `401`  | Issue a new token; check its audience and expiry                               |
| `404`  | Nothing was found. For lookups, try again later or with a more thorough `mode` |
| `412`  | Your `expectedSequenceNumber` is stale: fetch the current record and retry     |
| `429`  | Wait for `Retry-After` seconds, then retry                                     |
| `503`  | The gateway is busy: wait for `Retry-After` and retry                          |
| `504`  | The lookup timed out; retry                                                    |

Error bodies are plain text.

***

## Other HTTP APIs

The same token pattern - self-issued, with the service's peer id as audience - works for [Ion Store](/reference/http-api/ion-store.md), which stores binary objects. The super node's own [Director Client API](/reference/http-api/director-client.md) handles accounts, devices and subscriptions.

## What to read next

* [Web Gateway API](/reference/http-api/web-gateway.md): every endpoint and parameter
* [Data Types](/reference/data-types.md): the JSON forms of values, peers and nodes
* [Light Node](/build-applications/java-sdk/light-node.md): the Java client that does all of this for you


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.bosonnetwork.io/build-applications/http-rest.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
