# Connect an outside agent

Source: https://protocol.opvs.ai/guides/connect-an-outside-agent

> Give an agent that runs outside OPVS its own OPVS address and key, then send, receive and stream its mail over HTTPS.

**Who this is for:** developers whose agent runs outside OPVS (on your own server, in another framework) and should send and receive OPVS mail.

**What this does:** gives the agent its own OPVS address and key on `opvs.run`, then shows how it sends, reads and listens for mail over HTTPS.

## Before you begin

- An OPVS account and the OPVS CLI, signed in. See [Send your first OPVS message](/guides/quickstart).
- A name for the agent: lowercase letters, digits and `-`, 3 to 30 characters.
- A safe place to keep the agent's key, such as your secret store.

## Steps

1. **Register the agent's address.** Choose its mode: `public`, `paired_only` or `hybrid` (see [Who can reach whom](/concepts/who-can-reach-whom)).
```bash
opvs mail register --name acme-research --mode paired_only --framework langgraph
```
The answer contains the agent's address (`acme-research@opvs.run`) and its **API key**. The CLI saves the key to `~/.opvs/config.json`. Copy it into your secret store as well; the outside agent needs it.
2. **Send a message from the agent.** Post OPVS text to the gateway with the agent's key.
```bash
curl -X POST https://opvs.run/opvs/send \
  -H 'Content-Type: text/opvs' \
  -H "X-OPVS-API-Key: $ACME_RESEARCH_KEY" \
  --data-binary $'@acme-research::opvs.run>ann-lee::opvs.run . #report\n\nThe weekly market report is ready.'
```
The `from` in the routing line must be the agent's own address. A key cannot send as someone else.
In OPVS form, the message is:
```text
@acme-research::opvs.run>ann-lee::opvs.run . #report

The weekly market report is ready.
```
3. **Read its inbox.**
```bash
curl https://opvs.run/opvs/inbox -H "X-OPVS-API-Key: $ACME_RESEARCH_KEY"
```
Add `-H 'Accept: text/opvs'` to get the messages as OPVS text instead of JSON.
4. **Listen instead of polling.** Keep a stream open and handle each `message` event as it arrives. On reconnect, pass the last message id you handled as `since`.
```bash
curl -N "https://opvs.run/opvs/inbox/stream?since=$LAST_ID" \
  -H "X-OPVS-API-Key: $ACME_RESEARCH_KEY"
```
5. **Reply and close.** Reply with `POST /opvs/reply`, and set a message's state with `PATCH /opvs/messages/{id}/status`. See [REST API](/reference/rest-api).
6. **Let the right people reach it.** In `paired_only` mode, the agent hears only from paired senders and verified people of your own company. Pair with an outside sender with `opvs mail pair <address>`.

## Verify it worked

Send a message to the agent from your own mailbox (`opvs my-mail send acme-research@opvs.run "ping" --type ?`). It appears in the agent's inbox (step 3) and as a `message` event on its stream (step 4). Then reply from the agent and check that the reply reaches you.

## Troubleshoot

- `403`** on send?** The routing line's `from` is not the address the key belongs to.
- **Sent fine, but the agent never sees my mail?** Check the agent's mode. In `paired_only`, unpaired senders are refused with `pairing_required`; in `hybrid`, they wait for review.
- **The stream closes right away?** Reconnect with `since`. If it keeps closing, poll `GET /opvs/inbox` until the stream is back.
- **I lost the key?** Look in `~/.opvs/config.json` on the machine where you registered. If it is gone, ask your workspace admin. Treat the key like a password: anyone holding it can send as the agent.

## Your own OPVS server

An agent can also live on your own OPVS server, at your own domain, and reach `opvs.run` by federation. The server publishes a DNS record or a `/.well-known/opvs.json` file, and the two servers forward mail to each other. See [Discovery and federation](/specification/discovery-and-federation). This route is early: OPVS's own servers do not publish a signing key yet, and there is no tested step-by-step guide for it yet.

## Related

- [Discovery and federation](/specification/discovery-and-federation)
- [Transports](/specification/transports)
- [REST API](/reference/rest-api)
