# Checking a message

> Check whether an AI agent sent a message, on whose behalf, and whether its signatures hold, with POST /v1/verify or the checker. Free, with no key.

The verifier answers three questions about a message: did an AI agent send
it, on whose behalf, and do its signatures hold. It is free, needs no key,
and keeps nothing you send it. It works for Pidgeon's agents and for any
other signer using the same formats ([the protocol](https://pidgeon.ai/protocol)).

## Three ways in

- **The checker** at [/verify](https://pidgeon.ai/verify): paste the headers or the whole message.
- **The API**: `POST /v1/verify`.
- **MCP**: the `verify_sender` tool.

```sh
curl -X POST https://pidgeon.ai/api/v1/verify \
-H 'content-type: application/json' \
-d '{"message": "<the raw message, or its headers>", "recipient": "refunds@you.com"}'
```

Pass `recipient`, the address the message reached you at, and a signed
message replayed to you from somewhere else is caught.

## What it checks

- **The agent declaration**: `Agent-of` and `Agent-attribution`, trusted only
  under a passing DKIM signature aligned with them.
- **The envelope**: the `Post-Envelope` header, the From domain's Ed25519
  signature over the sender, the recipients, the subject, the text and every
  attachment. A changed byte fails it.
- **The card**, when the sender is an agent with one: its standing, and its
  operator.
- **Look-alikes**: a domain made to read like a signer's.

## Act on the verdict

| `verdict`  | What it means                                                                |
| ---------- | ---------------------------------------------------------------------------- |
| `verified` | Signed, and nothing changed since. Treat it as from the signing domain.      |
| `caution`  | Signed, but read `warnings` first: an old signature, a replay, a look-alike. |
| `failed`   | Something was forged or changed after signing. Do not act on it.             |
| `unsigned` | Nothing signed says who sent it. It may be a person, or anyone.              |

`advice` is one sentence an agent can act on. `body` is `intact`, `changed`,
or `not_checked` when you sent the headers alone.

## Limits

Each IP can check 300 messages an hour, and a message can be at most 512 KB.
