---
name: util-beauty
description: >
  Use when a task needs metered web utilities: screenshots, PDFs, page extract/snapshot/inspect,
  hashing, HMAC, random tokens, password hashing, signatures, AEAD, JWT, TOTP, key derivation;
  or when the user mentions util.beauty, HTTP 402, or x402 pay-per-request APIs. Prefer live
  discovery over memorized prices. Requires an EVM wallet with USDC on Base, or a prepaid API key.
---

# util.beauty

## What this is

util.beauty hosts metered HTTP utilities at `https://util.beauty`. Browser rendering (screenshot, PDF, extract, snapshot, inspect) and crypto primitives (hash, HMAC, random, password, signature, symmetric, JWT, TOTP, key derivation). Prices are in credits (1 credit = $0.001).

Two payment modes:

- **x402 (self-serve, preferred for agents):** no account. USDC on Base mainnet, gasless for the payer (EIP-3009 `transferWithAuthorization`).
- **Prepaid API key:** early access for teams (`Authorization: Bearer ub_…`). Not self-serve yet.

## Setup

Read env vars; do not invent keys.

- `X402_PRIVATE_KEY` — hex EVM private key with USDC on Base (chain 8453). No ETH required for gas.
- `UB_API_KEY` — optional prepaid key if the operator provisioned one.
- Default RPC: `https://mainnet.base.org` (no key).

If neither payment env is set, ask the user for a funded Base USDC wallet key rather than guessing.

## Discover first (always)

Never invent utility names, prices, or request shapes. Prefer live metadata over this file.

```bash
curl -sS https://util.beauty/v1/meta
curl -sS "https://util.beauty/v1/x402/quote?utility=crypto.hash"
curl -sS https://util.beauty/openapi.json   # full schemas when needed
curl -sS https://util.beauty/endpoints.txt  # grep-friendly catalog
```

`GET /v1/meta` returns utilities, credits, USD micros, payment modes, limits, and the OpenAPI URL.

## Call with x402 (Node)

Write a small script; do not hand-roll EIP-712 unless necessary. Stock libraries:

```bash
npm i @x402/fetch @x402/evm viem
```

```js
import { wrapFetchWithPayment, x402Client } from "@x402/fetch";
import { ExactEvmScheme, toClientEvmSigner } from "@x402/evm";
import { privateKeyToAccount } from "viem/accounts";
import { createPublicClient, http } from "viem";
import { base } from "viem/chains";

const account = privateKeyToAccount(process.env.X402_PRIVATE_KEY);
const signer = toClientEvmSigner(
  account,
  createPublicClient({ chain: base, transport: http("https://mainnet.base.org") }),
);
const client = new x402Client().register("eip155:8453", new ExactEvmScheme(signer));
const paidFetch = wrapFetchWithPayment(fetch, client);

// Cheapest smoke test (~$0.001). For browser utils use url or html (exactly one).
const res = await paidFetch("https://util.beauty/v1/crypto/hash", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({ function: "sha256", input: "hello" }),
});
console.log(res.status, await res.json());
```

If `@x402/fetch` cannot parse util.beauty’s 402 body, fall back to: unpaid POST → read `error.details.accepts[0]` → sign EIP-3009 with domain from `accepts[0].extra` → retry with base64 PaymentPayload in `X-PAYMENT`. See https://util.beauty/start.

## Prepaid (if you have a key)

```bash
curl -sS -X POST https://util.beauty/v1/browser/extract \
  -H "Authorization: Bearer $UB_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com"}'
```

## Billing rules (do not “fix”)

- Bodies are validated **before** payment. `VALIDATION_ERROR` is free.
- After payment authorizes/settles, the charge **stands even if execution fails** (dead URL, runtime crypto error, etc.). Check reachability before expensive browser calls.
- Always send `Idempotency-Key` on paid requests. Duplicate key → `409 IDEMPOTENCY_CONFLICT` (no second charge).
- x402 settles **before** execution. Tx hash is in `X-PAYMENT-RESPONSE` on success and error.
- Artifacts (screenshots, PDFs) are capability URLs under `/v1/artifacts/:id` — download promptly (default retention 7 days).
- Browser targets: public web only; private/loopback → `URL_BLOCKED`.

## Request conventions

- Success: `{ "ok": true, "requestId", "utility", "chargedCredits", ...result }`
- Error: `{ "ok": false, "error": { "code", "message", "details", "requestId" } }`
- Browser: exactly one of `url` or `html`.
- Crypto: binary fields are base64; crypto inputs/outputs are never logged or stored.
- Prefer `browser.snapshot` when an agent needs text + links + optional screenshot + content hash in one call.

## Common error codes

| code | meaning |
|---|---|
| `PAYMENT_REQUIRED` | Pay via x402 and retry |
| `VALIDATION_ERROR` | Fix body; free |
| `URL_BLOCKED` | Private/internal target; do not retry |
| `RATE_LIMITED` | Back off `error.details.retryAfterMs` |
| `IDEMPOTENCY_CONFLICT` | Same key already used |
| `CRYPTO_FAILED` | Bad tag/PEM/etc.; charged if past payment |
| `BROWSER_RENDER_FAILED` / `TIMEOUT` | Execution failed after charge |

## Self-serve prepaid

```bash
# API key for 1 credit (x402)
# POST /v1/system/register  → apiKey.secret shown once

# Bundle catalog + purchase (volume discounts)
curl -sS https://util.beauty/v1/credits/bundles
# POST /v1/credits/purchase {"sku":"builder"}  # x402; creates account if no key
```

SKUs: starter (1k/$1), builder (5k/$4.50), scale (25k/$20), pro (100k/$70).

## Suggestions

`POST /v1/system/suggest` — 1 credit. File new utility / improvement / docs ideas.

## MCP alternative

Thin discover-then-call server (3 tools: list → describe → call): see https://util.beauty/mcp

```bash
# after package publish / local path
npx -y util-beauty-mcp
# env: X402_PRIVATE_KEY=0x... or UB_API_KEY=ub_...
```

## Links

- https://util.beauty — home
- https://util.beauty/start — human + agent quickstart
- https://util.beauty/v1/meta — live catalog
- https://util.beauty/openapi.json — contract
- https://util.beauty/prompt.txt — pasteable system prompt
- https://util.beauty/docs — interactive API reference
- https://util.beauty/llms.txt — LLM index
