# API Scaffolding

API Scaffolding is a separate Valiron product for exposing existing HTTPS APIs through hosted, agent-facing URLs. It can add x402 or MPP payment handling, optional Valiron trust checks, rate limits, upstream forwarding, and usage logs without requiring immediate SDK middleware integration.

Use this flow when Valiron should host the payment and optional trust layer for an existing HTTPS API:

```text
Agent or client
  -> Valiron-hosted wrapper URL
  -> x402 or MPP payment check
  -> optional Valiron trust check
  -> provider's existing API
  -> response returned through Valiron
```

> **Important: protect the origin.** A hosted wrapper evaluates and logs only
> requests sent to its Valiron URL. It is not a network firewall in front of a
> separately public API origin. If callers can reach your origin directly, they
> can bypass the wrapper's payment, trust, rate-limit, and analytics path.
> Publish the generated wrapper URL as the agent-facing URL and configure your
> origin to accept only authenticated requests from Valiron.

The wrapper is intentionally narrow: Valiron forwards valid HTTP requests to an existing upstream API. It does not need direct database access, internal service access, or provider infrastructure credentials beyond the optional upstream auth secret needed to call the API.

## When To Use This

Use API Scaffolding when:

- You already have an HTTPS API and want to sell per-call access to agents.
- You want x402 or MPP payment challenges without implementing those protocols yourself.
- You want Valiron trust checks before paid traffic reaches your API.
- You need a no-code or low-code path from an existing API to an agent-compatible endpoint.

Use the SDK middleware instead when:

- You want payments to be handled entirely by your own server.
- You need custom payment terms, subscriptions, account billing, or business-specific authorization.
- Valiron should run directly in the API backend as the primary trust and policy enforcement layer.

## Provider Setup

Providers configure one wrapper per public endpoint.

| Field | Required | Description |
|-------|----------|-------------|
| Public path | Yes | Path callers use on Valiron, for example `/weather`. |
| HTTP method | Yes | `GET`, `POST`, `PUT`, `PATCH`, `DELETE`, or `HEAD`. |
| Upstream base URL | Yes | Existing HTTPS API base URL, for example `https://api.example.com`. |
| Price per call | Yes | USD amount charged for paid requests. Use `0` for a free wrapper. |
| Payment protocol | Yes | `x402` or `MPP`. |
| Payment network | Yes | x402: `eip155:8453` or `eip155:84532`; MPP: `tempo:4217` or `tempo:42431`. |
| Payout wallet | Paid only | EVM address receiving payment. |
| Upstream auth | Required to prevent origin bypass | Auth Valiron adds when forwarding to your upstream. Use `hmac` for a public origin. |
| Rate limit | No | Max requests per minute per client. |
| Trust check | No | Whether callers must pass Valiron agent trust evaluation before forwarding. |

Example existing API:

```text
GET https://api.example.com/weather
```

Example Valiron URL:

```text
GET https://valiron-edge-proxy.onrender.com/wrap/{operatorId}/weather
```

Valiron preserves query strings and appends the public wrapper path to the upstream base URL. If your upstream base URL is `https://api.example.com/v1` and your public path is `/weather`, Valiron forwards to:

```text
https://api.example.com/v1/weather
```

## Dashboard Flow

1. Open [valiron.co/dashboard](https://www.valiron.co/dashboard).
2. Go to **Make API Agent-Ready**.
3. Click **Make API Agent-Ready**.
4. Enter the upstream URL, public path, method, price, protocol, network, and payout wallet.
5. Choose whether Valiron trust checks are required.
6. Configure upstream authentication. For a public origin, choose `hmac` and
   store the same secret in your origin's verification middleware.
7. Create the wrapper.
8. Distribute only the generated Valiron URL to agent clients or API customers.
9. Verify that a direct request to your origin is rejected and a request to the
   wrapper is recorded in Valiron call logs.

Create, list, and deactivate wrappers in the dashboard.

## Calling A Wrapper

Call the generated URL directly:

```bash
curl -i https://valiron-edge-proxy.onrender.com/wrap/{operatorId}/weather
```

For a free wrapper, Valiron forwards immediately and returns the upstream response with Valiron wrapper headers:

```text
x-valiron-wrapper-id: ...
x-valiron-payment-protocol: free
x-valiron-trust-enabled: false
```

For a paid x402 wrapper without payment, Valiron returns `402` and an x402 payment challenge:

```text
HTTP/1.1 402 Payment Required
x-payment-required: ...
```

For a paid MPP wrapper without payment, Valiron returns `402` and an MPP challenge:

```text
HTTP/1.1 402 Payment Required
WWW-Authenticate: Payment ...
```

## x402 Paid Client

Use an x402-capable client to retry with payment. The example below uses:

- `@x402/fetch`
- `@x402/core/client`
- `@x402/evm/exact/client`
- `viem/accounts`

Minimal client shape:

```typescript
import { wrapFetchWithPayment } from "@x402/fetch";
import { x402Client } from "@x402/core/client";
import { ExactEvmScheme } from "@x402/evm/exact/client";
import { privateKeyToAccount } from "viem/accounts";

const account = privateKeyToAccount(process.env.BUYER_PRIVATE_KEY as `0x${string}`);

const client = new x402Client();
client.register("eip155:*", new ExactEvmScheme(account));

const fetchWithPayment = wrapFetchWithPayment(fetch, client);

const response = await fetchWithPayment(
  "https://valiron-edge-proxy.onrender.com/wrap/{operatorId}/weather",
  { method: "GET", headers: { "x-agent-id": "25459" } }
);

console.log(response.status);
console.log(await response.text());
```

The buyer wallet must hold the required token on the selected x402 network. For Base mainnet, the default production path expects USDC on Base.

## MPP Paid Client

Valiron MPP support uses the official `mppx` SDK with the Tempo `charge` intent.

Server behavior:

- Unpaid request returns `402`.
- Response includes `WWW-Authenticate: Payment ...`.
- Paid request includes `Authorization: Payment ...`.
- Successful paid response includes `Payment-Receipt`.

Recommended testnet client flow:

```bash
pnpm exec mppx account create
pnpm exec mppx https://valiron-edge-proxy.onrender.com/wrap/{operatorId}/research
```

Use `tempo:42431` for Tempo testnet and `tempo:4217` for Tempo mainnet.

Default Tempo currencies from `mppx`:

| Network | Chain ID | Default currency |
|---------|----------|------------------|
| Tempo mainnet | `4217` | USDC (`0x20C000000000000000000000b9537d11c60E8b50`) |
| Tempo testnet | `42431` | pathUSD (`0x20c0000000000000000000000000000000000000`) |

## Optional Trust Checks

When `trustEnabled` is `false`, Valiron only handles payment, rate limiting, upstream auth, and forwarding.

When `trustEnabled` is `true`, callers must identify the agent:

```text
x-agent-id: 25459
```

Valiron evaluates the agent before forwarding. If the agent is denied, the upstream API is not called.

Use trust checks when:

- You want to block risky agents even if they can pay.
- You want route decisions and call logs tied to agent IDs.
- You plan to vary pricing, limits, or access based on trust tiers.

Use payment-only wrappers when:

- You want the lowest-friction paid endpoint.
- You do not need agent identity yet.
- You are testing x402 or MPP integration.

## Upstream Auth

Valiron stores the configured secret encrypted and injects or derives it only
when forwarding a request that has reached the wrapper. This is how your origin
distinguishes an authenticated wrapper request from a direct public request.

For a public API origin, configure upstream authentication before announcing or
indexing the wrapper. Otherwise, a caller can send traffic directly to the
origin and bypass Valiron entirely. `none` is appropriate only when the origin
is already inaccessible to untrusted callers or bypass is intentionally
acceptable.

Supported auth modes:

| Mode | Behavior |
|------|----------|
| `none` | No upstream auth is added. |
| `bearer` | Adds `Authorization: Bearer <secret>`. |
| `api_key` | Adds the secret to the configured header name. |
| `hmac` | Signs the request using the secret and adds signature headers. |

The calling agent never sees your upstream secret.

### Recommended production pattern: HMAC origin verification

Choose `hmac` for an origin that is publicly reachable. Valiron sends:

```text
x-valiron-signature: sha256=<hex HMAC>
x-valiron-timestamp: <Unix seconds>
```

Your origin must reject requests when the signature is missing, invalid, or too
old. Verify the signature against the request method, public wrapper path, raw
body SHA-256, and timestamp with the shared secret configured on the wrapper.
Use constant-time signature comparison and a short timestamp window to reduce
replay risk.

Do **not** treat headers such as `x-valiron-wrapper-id`,
`x-valiron-payment-protocol`, or `x-valiron-trust-enabled` as proof that a
request came through Valiron. They are request metadata, not a credential, and
can be forged by a caller that reaches your origin directly.

### Origin-lockdown checklist

Before production:

1. Set `upstreamAuthType` to `hmac` and configure a unique secret.
2. Deploy origin middleware that verifies the HMAC and timestamp before the API
   handler runs.
3. Make the Valiron `/wrap/{operatorId}/{path}` URL the only public URL in
   agent discovery metadata, examples, and client configuration.
4. Send a direct request to the origin without the signature and confirm a
   `401` or `403` response.
5. Send a request through the wrapper and confirm the expected payment/trust
   result and a corresponding Valiron call-log entry.

## Security Defaults

In production, Valiron wrappers:

- Require HTTPS upstream URLs.
- Block localhost, private IP ranges, link-local IPs, metadata hosts, and internal hostnames.
- Resolve upstream DNS and block private resolved IPs.
- Strip hop-by-hop and sensitive inbound headers before forwarding.
- Do not forward inbound `Authorization`, `Cookie`, `x-payment`, or `payment-signature` headers to the upstream.
- Add Valiron wrapper metadata headers to forwarded requests.
- Apply per-endpoint rate limits.
- Enforce request body size limits.
- Time out slow upstream calls.

## Current Limits

The first wrapper release supports:

- Per-call x402 payments.
- Per-call MPP Tempo charge payments.
- Free wrappers.
- Optional trust checks.
- Optional upstream auth injection.
- Per-endpoint rate limits.

It does not yet support:

- MPP sessions or subscriptions.
- Multi-upstream routing.
- Cross-protocol fallback on a single endpoint.
- Non-HTTPS production upstreams.
