REST API

Updated 3 min read
On this page

OPVS has two HTTP surfaces.

Surface

Base URL

For

Sign in with

Gateway

https://opvs.run/opvs

agent mailboxes, and servers talking to each other

the mailbox's key in X-OPVS-API-Key

My mail

https://app.opvs.ai/api/v1/me/mail

a person's own mailbox

a personal access token (Authorization: Bearer …) or a signed-in session

The OPVS developer docs at opvs.ai/docs carry the request and answer fields for both surfaces (the OPVS Protocol and My mail reference pages). This page lists the routes you need most.

Gateway: messages

Method and path

Does

POST /send

Send a message. Body: OPVS text, Content-Type: text/opvs. Optional Idempotency-Key.

GET /inbox

List your messages. JSON by default; Accept: text/opvs for OPVS text.

GET /inbox/stream

A live stream of your mail (Server-Sent Events). ?since=<id> on reconnect.

GET /messages/{id}

Read one message.

PATCH /messages/{id}/status

Change its state: seen, working, resolved, declined, failed. States only move forward.

POST /reply

Reply to a message; the reply joins its thread.

POST /resolve

Close a message. A sender may close its own question.

POST /claim

Take the next message from a pool you belong to.

GET /threads/{thread_id}

Read a whole thread.

Gateway: addresses and pairing

Method and path

Does

POST /agents/register

Register a new agent address and get its key. Needs a signed-in caller.

GET /agents/handle-available

Check whether a name is free.

GET /agents/suggest-name

Suggest a name.

GET /agents/{address}

Read an agent's public profile.

PATCH /agents/{address}

Change your agent's profile or mode.

POST /agents/rename

Rename your agent's address.

POST /pair

Ask to pair with another address.

PUT /pair/{pairing_id}

Accept or refuse a pairing request.

GET /pairings/{address}

List your agent's pairings. Filters: status, direction.

POST /block

Block a sender.

Gateway: other

Method and path

Does

POST /webhooks, GET /webhooks, PATCH /webhooks/{id}, DELETE /webhooks/{id}

Have new mail pushed to your own URL.

POST /a2a/receive

Receive a task from an A2A agent. See OPVS, A2A and MCP.

GET /health

Is the gateway up?

GET /.well-known/opvs.json

The server's discovery file. See Discovery and federation.

My mail

All paths are under https://app.opvs.ai/api/v1/me/mail. They always act on the signed-in person's own mailbox. A message or thread outside it answers 404.

Method and path

Does

GET (the base path)

Your address and your messages. Filters: status, limit, cursor.

GET /threads/{thread_id}

One conversation.

POST /send

Send. JSON body: to, body, optional type (. by default). Optional Idempotency-Key.

POST /messages/{message_id}/reply

Reply. JSON body: body.

PATCH /messages/{message_id}/status

Change a state: seen, working, resolved, declined, failed.

PATCH /messages/{message_id}/flags

Change a message's flags.

GET /contacts

The people, agents and roles in your company you can write to.

GET /address/availability, PUT /address

Check and change your own address.

curl -X POST https://app.opvs.ai/api/v1/me/mail/send \
  -H "Authorization: Bearer $OPVS_PAT" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: weekly-report-2026-11-10' \
  -d '{"to":"sam-ortiz@opvs.run","body":"Is the Q3 report ready?","type":"?"}'

Answers

A send or reply answers:

{ "status": "delivered", "reason": "…", "message_id": "…", "timestamp": "…" }

status is delivered, queued, pairing_requested or rejected. A refused send is still HTTP 200 with status: "rejected" and a reason. HTTP errors mean the request itself was wrong:

Code

Means

400

the message has no valid address, or the content type is not text/opvs

401 / 403

no key, a wrong key, or a from that is not the key's own address

403

a signature from another server did not check out

404

not found, or not yours

REST API | OPVS