# API Protocol

The API Protocol enables a peer to call other peers that will make an API request to a separate server or process that is hosting an API. For example, a node can have a separate server or process, compartmentalized from the P2P process or server, and when a peer wants to open a stream to your peer to perform a task, the business logic for that task can be in a separate server or process that runs an API and returns the results from that separate process back to the calling peer.&#x20;

This is useful for use cases where a peer should have multiple servers (one server handles the P2P layer, and other server(s) handle the business logic), such as hosting multiple models on multiple servers.

<figure><img src="/files/Tnv7z7D31hSKpveglqTZ" alt=""><figcaption></figcaption></figure>

### Configuration

This is a protocol that other peers can call, which ultimately calls an API and returns a result. We need to set up what the API endpoint or endpoints are.

In the API protocol, when a peer calls another peer, it will call it with the following arguments:

```
destination: Multiaddr,
route: str,
method: str = "GET",
headers: dict = None,
body: bytes = b"",
```

See [Calling Another Peer](#calling-another-peer).

Therefore, the `route` is the key that maps to a `url` endpoint, and if the URL endpoint can be streamed.

#### JSON

The preferred way is to set up a JSON file because it can be updated in realtime without requiring a restart of the P2P layer.

In this example, if a peer calls to another peer with the route "health", the receiving peer will receive this request, and it will route to the health URL that will call a seperate process that is running an API and return the result to the calling peer.

```python
{
    "health": {
        "url": "https://127.0.0.1:8000/health",
        "stream": false
    },
    "inference": {
        "url": "https://127.0.0.1:8000/v1/inference",
        "stream": true
    },
    "events": {
        "url": "https://127.0.0.1:8000/v1/events",
        "stream": false
    }
}
```

#### Configuration Class

You can optionally configure the API protocol using the ApiProtocolConfig dataclass.

{% hint style="info" %}
This method requires a full node restart for updates. Therefore, it's suggested to use the JSON configuration so when making updates to the separate process, the peer never needs to restart and reconnect to the subnet's network.
{% endhint %}

```python
config = ApiProtocolConfig(
    routes={
        "health": {
            "url": "https://127.0.0.1:8000/health",
            "stream": False,
        },
        "inference": {
            "url": "https://127.0.0.1:8000/v1/inference",
            "stream": True,
        },
        "events": {
            "url": "https://127.0.0.1:8000/v1/events",
            "stream": False,
        },
    },
)
```

### Initializing Protocol

To initialize the API protocol, by default, it requires the peer's host (the peer's host is the base layer for managing the connections to other peers) and the configuration.

```python
api_protocol = ApiProtocol(host=host, config=config)
```

### Calling Another Peer

Calling a peer requires their multiaddress and the key (route) of the intended call.

#### Unary

```python
await api_protocol.call_remote(
    remote_peer_multiaddr,
    "health",
)
```

#### Stream

```python
async for result in api_protocol.stream_remote(
    remote_peer_multiaddr,
    "inference",
):
    print(f"result : {result }")
```


---

# Agent Instructions: Querying This Documentation

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

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.hypertensor.org/copy-of-subnet-template/communication/api-protocol.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
