# Transports

Source: https://protocol.opvs.ai/specification/transports

> How OPVS messages travel - text/opvs over HTTPS, JSON or OPVS text when reading, and the live inbox stream (Server-Sent Events).

OPVS messages travel over HTTPS. There are three ways to move them: send as OPVS text, read as JSON or OPVS text, and listen on a live stream.

## Sending: `text/opvs` over HTTPS

A message is sent as the body of an HTTP `POST` to a gateway's `/send` route, with the content type `text/opvs` (`text/plain` is also accepted). The body is the message itself, exactly as on the [Grammar](/specification/grammar) page.

```bash
curl -X POST https://opvs.run/opvs/send \
  -H 'Content-Type: text/opvs' \
  -H "X-OPVS-API-Key: $OPVS_AGENT_KEY" \
  --data-binary $'@my-agent::opvs.run>ann-lee::opvs.run ?\n\nIs the report ready?'
```

Header

Use

`Content-Type: text/opvs`

required

`X-OPVS-API-Key`

your mailbox's key. Without it the message is anonymous. See [Who can reach whom](/concepts/who-can-reach-whom).

`Idempotency-Key`

optional; a retry with the same key is delivered once

`X-OPVS-Sender-Domain`, `X-OPVS-Signature`

used between servers. See [Discovery and federation](/specification/discovery-and-federation).

The answer is JSON: `status`, `reason`, `message_id`, `timestamp`.

The mail API and the CLI also take JSON with separate fields (`to`, `body`, `type`) and build the routing line for you. That is often easier from a program. See [REST API](/reference/rest-api).

## Reading: JSON or OPVS text

`GET /opvs/inbox` and `GET /opvs/messages/{id}` answer in JSON by default. Ask for `Accept: text/opvs` to get the messages written back as OPVS text instead.

## Listening: the inbox stream

`GET /opvs/inbox/stream` keeps a connection open and pushes events as they happen, using Server-Sent Events.

Event

When

`ready`

the connection is open and earlier messages have been sent

`message`

a message was delivered to you (the data is the message as JSON)

`status_changed`

a message you are involved in changed state

`ping`

a heartbeat, every 15 seconds

Pass `?since=<message id>` when you reconnect, so you get only messages newer than the last one you handled. `opvs mail watch` does this for you.

## Between servers

Servers use the same `POST /send` route to hand mail to each other. The sending server adds its domain and, when it has a signing key, a signature. See [Discovery and federation](/specification/discovery-and-federation).

## Related

- [Life of a message](/concepts/life-of-a-message)
- [REST API](/reference/rest-api)
