---
name: ucode-sms
description: Rent a virtual phone number and wait for one lawful SMS verification code (OTP). Use when a form asks for SMS verification, a QA/E2E test needs an OTP, or the user wants a temporary number for privacy or travel — never for bulk account farming.
---

# Ucode agent rail

Virtual numbers for lawful verification, QA, travel, and privacy only. Add credits with **USDC on Base** (x402), then rent. You can also pay per SMS.

## Base

`https://app-api.ucodesim.com`

Public docs: https://ucode.uk/agents  
Discovery: `GET /api/v1/agent` and `GET /.well-known/x402` (also https://ucode.uk/.well-known/x402)  
MCP: `https://mcp.ucodesim.com/mcp` — call **ucode_agent_billing** (no login) for packs and how to pay.

Humans (ChatGPT / iOS / Android / Web): add credits at https://ucode.uk/app/credits — not this rail.

## Add credits (prepaid — use this)

`GET /api/v1/agent/credits` — same packs and sticker prices as the panel (plus `payTo`). Use a `packageId` from that list. Aliases `starter` / `plus` / `pro` map to the smallest, popular, and largest pack.

`POST /api/v1/agent/credits`

```json
{
  "pack": "<packageId from GET>",
  "acceptLawfulUse": true
}
```

If the response is **402**, pay the quoted **USDC on Base** with x402 to `payTo`, then retry the **same POST** with header `X-PAYMENT` (or `PAYMENT-SIGNATURE`).

Save **`data.apiKey`** (`uc_live_…`) — shown once. Then:

- Balance: `GET /api/v1/agent/me` with `Authorization: Bearer uc_live_…`
- Rent: `POST /api/v1/agent/activations` with that Bearer key (no extra crypto per SMS)

Failed SMS refunds **credits** automatically. On-chain USDC is not returned.

## Pay per SMS (optional)

`GET /api/v1/agent/quote?service=wa&country=0`

`POST /api/v1/agent/activations`

```json
{
  "service": "wa",
  "country": 0,
  "purpose": "qa",
  "acceptLawfulUse": true
}
```

`purpose` must be one of: `qa`, `privacy`, `travel`, `business`.

**402** → pay USDC on Base → retry with `X-PAYMENT`. The first successful (or credits-held) payment also issues `apiKey` once so leftover credits are spendable.

## Wait for SMS

Use `data.pollUrl` with `?pollToken=` from the rent response. Poll every 3–5 seconds until `data.sms` is non-empty or `status` is cancelled/refunded (~20 minutes).

## Rules

- Do not use this to create bulk or fake accounts, evade bans, or break a platform’s terms.
- If no SMS arrives, do not retry-spam; wait for the automatic refund window.
- Prefer Fast/Standard routes already priced in the quote. What you pay is what you were quoted.
