# SendFax.sh -- Full Reference > Send real faxes over HTTP. One API call, paid per page with x402 or MPP > (USDC) -- no account, no API key. Humans can send via Stripe Checkout. SendFax.sh is a single-purpose service: send a fax. Agents call a paid HTTP API and settle per request in USDC over x402 or MPP; there are no accounts and no API keys, because the payment itself is the credential. Humans use a drag-and-drop page and pay with Stripe. Faxes are delivered via Telnyx Programmable Fax and are real-time -- the PDF is streamed to the carrier and deleted after sending. We never store your document. Base URL: `https://sendfax.sh` --- ## Pricing - **$0.05 per page.** - Agent rails (x402/MPP) settle in USDC (6 decimals): $0.05 = `50000` base units per page. No minimum. - Human Stripe flow: `max($0.50, ceil(pages x $0.05))` -- Stripe enforces a $0.50 minimum charge. - No credit top-up and no get-started minimum: a one-page fax costs one page. - (Cost basis: Telnyx blended vendor cost is ~$0.014/page all-in.) --- ## Authentication There is none. Payment is the credential. - No accounts, no sign-up, no API keys, no OAuth. - Agents: each `POST /api/v1/faxes` is authorized by a per-request x402 or MPP payment (details below). Nothing to store or rotate. - Status polling (`GET /api/v1/faxes/{id}`) is free and unauthenticated; the fax id is an unguessable capability. - Humans: Stripe Checkout completion authorizes the send. - OAuth/OpenID/PKCE discovery documents are intentionally absent -- there is no durable identity to authenticate. --- ## API Reference All responses are JSON. Errors use `application/problem+json` (RFC 9457): `{ "type", "title", "status", "detail" }`. ### POST /api/v1/faxes -- send a fax (agent, paid) `multipart/form-data`: | Field | Type | Notes | |------------|----------------|------------------------------------------| | `document` | file (PDF) | Unencrypted PDF, <=20 MB. | | `to` | string (E.164) | Destination fax number, e.g. `+14155550123`. | **First call -> HTTP 402 Payment Required.** The price ($0.05/page, USDC) is advertised two ways so any capable client can pay: - **x402**: response header `PAYMENT-REQUIRED` + a JSON body with an `accepts` array of payment requirements. Pay, then retry the identical request with an `X-PAYMENT` header. - **MPP** (mpp.dev): response header `WWW-Authenticate: Payment` describing the same charge. Pay, then retry with the `PAYMENT` header. Example 402 body: ```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 USDC base units (6 decimals) x page count. **Retry with payment -> HTTP 202 Accepted:** ```json { "id": "fax_9f3c2a...", "statusUrl": "https://sendfax.sh/f/fax_9f3c2a..." } ``` Error statuses: `400` (missing/invalid `document` or `to`, or invalid/encrypted PDF), `413` (PDF > 20 MB), `402` (payment required / invalid payment). ### GET /api/v1/faxes/{id} -- status (free) Returns the public view of the fax (`FaxPublic`): ```json { "id": "fax_9f3c2a...", "status": "delivered", "pageCount": 1, "toMasked": "**** 0123", "failureReason": null, "createdAt": 1752096000000, "terminalAt": 1752096010000 } ``` Unknown id -> `404` problem+json. **FaxPublic fields:** | Field | Type | Notes | |-----------------|-------------------|-------------------------------------------| | `id` | string | Fax id (also the status URL slug). | | `status` | enum | See status values below. | | `pageCount` | integer | Pages in the document. | | `toMasked` | string | Destination redacted to last 4, e.g. `**** 0123`. | | `failureReason` | string \| null | Set when `status = failed`. | | `createdAt` | integer (epoch ms)| When the job was created. | | `terminalAt` | integer \| null | When the job reached a terminal state. | The raw destination number and all Telnyx internals are deliberately excluded. **Status values:** `awaiting_payment` (human upload, checkout not done) -> `paid` -> `queued` -> `media_processed` -> `sending` -> `delivered`. Terminal: `delivered`, `failed` (see `failureReason`), `expired` (unpaid upload past TTL). ### Human-flow endpoints (used by the /human page) - `POST /api/v1/uploads` -- `multipart/form-data` (`document`, `to`). Validates and page-counts the PDF (never stored), returns `{ id, pageCount, amountCents }`. - `POST /api/v1/checkout` -- JSON `{ id }` -> `{ url }`, the Stripe Checkout hosted URL. On completion the user is redirected to `/f/{id}`. --- ## Sending a fax -- worked example (agent) ```bash # 1. Submit (returns 402) curl -sS https://sendfax.sh/api/v1/faxes \ -F document=@invoice.pdf \ -F to=+14155550123 # 2. Your x402/MPP client pays the advertised amount, then retries the same # request with the payment header (X-PAYMENT for x402, PAYMENT for MPP). # 3. On 202 you get { "id": "...", "statusUrl": "..." }. # 4. Poll until terminal: curl -sS https://sendfax.sh/api/v1/faxes/fax_9f3c2a ``` --- ## Privacy Real-time fax. The PDF is uploaded directly to Telnyx (`POST /v2/media`), sent by reference, and deleted from Telnyx after the send -- we never persist the document ourselves. Our store keeps only process metadata: ids, statuses, page counts, timestamps, and the last-4 mask of the destination. The full destination number is nulled at terminal state. Telemetry never logs PDF content, filenames, payer details, or destination numbers. Carrier guarantees: faxes are delivered over Telnyx, a HIPAA-compliant real-time T.38 fax carrier (nothing stored on either end) certified for SOC 2 Type II, ISO 27001, PCI DSS, and GDPR. --- ## Discovery surfaces - `https://sendfax.sh/llms.txt` -- this file's index. - `https://sendfax.sh/openapi.json` -- OpenAPI 3.1 spec. - `https://sendfax.sh/quickstart.md`, `/auth.md`, `/SKILL.md` -- docs. - `https://mcp.sendfax.sh/mcp` -- remote, authless MCP server (Streamable HTTP; SSE fallback at `/sse`). Tools: `send_fax`, `get_fax_status`, `get_payment_instructions`. Connect: `claude mcp add --transport http sendfax https://mcp.sendfax.sh/mcp`. - `https://sendfax.sh/.well-known/agent-card.json` -- A2A agent card. - `https://sendfax.sh/.well-known/ai-plugin.json` -- plugin manifest. - `https://sendfax.sh/.well-known/mcp/server-card.json` -- MCP capability card (mirrors the live MCP server's tools + resources). - `https://sendfax.sh/.well-known/api-catalog` -- RFC 9727 API linkset. - `https://sendfax.sh/.well-known/ucp` -- UCP product profile. --- ## Notes - **Test mode**: no real fax line is provisioned yet. The pipeline simulates the `queued -> media_processed -> sending -> delivered` transitions on a timer, so the full flow is demonstrable end to end. - Status page URLs (`/f/{id}`) are shared by human and agent sends. - Support: support@sendfax.sh