# SendFax.sh -- Quickstart (agents)

Send a real fax in four steps. No account, no API key: you authorize each send
by paying for it with x402 or MPP (USDC).

Base URL: `https://sendfax.sh`

## 1. Submit the fax

`POST /api/v1/faxes` as `multipart/form-data`:

| Field      | Type            | Notes                                   |
|------------|-----------------|-----------------------------------------|
| `document` | file (PDF)      | The document to fax. Unencrypted, <=20 MB. |
| `to`       | string (E.164)  | Destination fax number, e.g. `+14155550123`. |

SendFax delivers to the US, Canada, Mexico, and St. Pierre & Miquelon. A number
outside those countries returns `422` before any payment.

```bash
curl -sS https://sendfax.sh/api/v1/faxes \
  -F document=@invoice.pdf \
  -F to=+14155550123
```

## 2. Pay (HTTP 402)

The first call returns **HTTP 402 Payment Required**. The response advertises
the price ($0.05/page, USDC) two ways so any capable client can pay:

- **x402**: a JSON body with an `accepts` array of payment requirements, plus a
  `PAYMENT-REQUIRED` response header. Pay, then retry the exact same request
  with an `X-PAYMENT` header carrying the payment payload.
- **MPP** (Machine Payment Protocol, mpp.dev): a `WWW-Authenticate: Payment`
  response header describing the same charge. Pay, then retry with the
  `PAYMENT` header your MPP client produces.

```
HTTP/1.1 402 Payment Required
WWW-Authenticate: Payment
PAYMENT-REQUIRED: <base64 payment requirements>
x-payment-deposit-mode: stripe-deposit
x-payment-deposit-network: base
x-payment-deposit-address: 0x157a57423869bf2666d3998b1319c2263ce852bb
x-payment-deposit-token: 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
x-payment-deposit-amount: 0.050000
Content-Type: application/json

{
  "x402Version": 1,
  "error": "payment required",
  "accepts": [
    {
      "scheme": "exact",
      "network": "base",
      "asset": "USDC",
      "maxAmountRequired": "50000",
      "resource": "https://sendfax.sh/api/v1/faxes",
      "description": "Fax transmission -- $0.05/page",
      "mimeType": "application/json"
    }
  ]
}
```

`maxAmountRequired` is in USDC base units (6 decimals): `50000` = $0.05 for a
one-page fax; multiply by the page count for longer documents.

**Settlement is by Stripe deposit mode** (no facilitator, no CDP, no signed
authorization). The 402's `x-payment-deposit-*` headers give you a fresh
per-request address: send **exactly** `x-payment-deposit-amount` USDC to
`x-payment-deposit-address` on `x-payment-deposit-network` as a plain ERC-20
`transfer`. Stripe watches the chain and captures it. (The x402/MPP challenge is
still advertised for wire-format discovery, but this direct transfer is the wired
settlement path.)

## 3. Retry to claim -> accepted

Once you have sent the USDC, retry the **identical** request (same `document` +
`to`, **no payment header**). The server polls the PaymentIntent and, as soon as
your transfer is detected, returns **HTTP 202 Accepted**; until then it returns
the same 402 (same address, safe to retry), so poll every few seconds:

```json
{ "id": "fax_9f3c2a...", "statusUrl": "https://sendfax.sh/f/fax_9f3c2a..." }
```

## 4. Poll status (free)

`GET /api/v1/faxes/{id}` -- no payment required. Poll until a terminal status:

```json
{
  "id": "fax_9f3c2a...",
  "status": "delivered",
  "pageCount": 1,
  "toMasked": "**** 0123",
  "failureReason": null,
  "createdAt": 1752096000000,
  "terminalAt": 1752096010000
}
```

Status progression: `queued -> media_processed -> sending -> delivered`, or
`failed` (see `failureReason`). Terminal statuses are `delivered`, `failed`,
and `expired`.

## Notes

- **Privacy**: real-time fax. The PDF is streamed to Telnyx and deleted after
  sending -- never stored by us. The destination number is redacted to its last
  4 digits (`toMasked`) once the job reaches a terminal state.
- **Errors** use `application/problem+json` (RFC 9457): `{ type, title, status,
  detail }`.
- **Test mode**: no real fax line is provisioned yet, so the pipeline simulates
  the `queued -> ... -> delivered` transitions on a timer. The full flow is
  demonstrable end to end.
