Purchase Subname (x402 Payment)
Register a new ENS subname with x402 micropayment. Required when free tier is exhausted.
Endpoint​
POST /api/subnames/{parent}/purchase
Authentication​
x402 Payment Required — Include payment header with USDC on Base network.
x402 Payment Flow​
1. Client calls endpoint without payment
2. Server returns 402 with payment requirements
3. Client makes USDC payment to facilitator
4. Client retries request with x-payment header
5. Server verifies payment and registers name
Request Body​
{
"name": "premium",
"owner": "0x701B4937e6c943789ffA74CC8601813b2D87B454",
"records": {
"description": "My premium subname"
}
}
| Field | Type | Required | Description |
|---|---|---|---|
name | string | âś… | Subname label to register |
owner | string | âś… | Ethereum address that will own the subname |
records | object | ❌ | Optional ENS text records |
Response (402 - Payment Required)​
When called without payment:
{
"error": "Payment Required",
"code": "PAYMENT_REQUIRED",
"message": "This name requires $4.97 USDC",
"x402": {
"accepts": [{
"scheme": "exact",
"network": "eip155:8453",
"asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"payTo": "0xF499102c8707c6501CaAdD2028c6DF1c6C6E813b",
"amount": "4970000",
"maxTimeoutSeconds": 300,
"extra": { "name": "USD Coin", "version": "2" }
}],
"resource": {
"url": "POST /api/subnames/aboutme.eth/purchase",
"description": "Register premium.aboutme.eth",
"mimeType": "application/json"
}
}
}
Response (Success with Payment)​
{
"success": true,
"parent": "aboutme.eth",
"name": "premium",
"fullName": "premium.aboutme.eth",
"owner": "0x701B4937e6c943789ffA74CC8601813b2D87B454",
"pricing": {
"price": 4.97,
"priceFormatted": "$4.97",
"tier": "short",
"paidAmount": 4.97
},
"paymentReceived": true,
"message": "Successfully registered premium.aboutme.eth",
"timestamp": "2024-02-10T14:30:00.000Z"
}
Examples​
JavaScript with x402 SDK​
import { createX402Client } from '@x402/client';
const client = createX402Client({
network: 'base',
signer: wallet // ethers.js signer
});
async function purchaseSubname(parent, name, owner, records = {}) {
const response = await client.fetch(
`https://api.web3identity.com/api/subnames/${parent}/purchase`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name, owner, records })
}
);
return response.json();
}
// Purchase a premium name
const result = await purchaseSubname(
'aboutme.eth',
'code', // 4-char = $4.97
'0x701B4937e6c943789ffA74CC8601813b2D87B454'
);
console.log(`Registered: ${result.fullName}`);
console.log(`Paid: ${result.pricing.priceFormatted}`);
Manual x402 Flow​
async function purchaseWithManualPayment(parent, name, owner, wallet) {
// 1. Get price first
const priceRes = await fetch(
`https://api.web3identity.com/api/subnames/${parent}/${name}/price`
);
const priceData = await priceRes.json();
if (!priceData.available) {
throw new Error('Name is not available');
}
console.log(`Price: ${priceData.pricing.priceFormatted}`);
// 2. Make initial request to get payment requirements
const response = await fetch(
`https://api.web3identity.com/api/subnames/${parent}/purchase`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name, owner })
}
);
if (response.status === 402) {
const paymentReq = await response.json();
const accept = paymentReq.x402.accepts[0];
// 3. Make USDC payment
// ... payment logic with wallet ...
// 4. Retry with payment header
const retryResponse = await fetch(
`https://api.web3identity.com/api/subnames/${parent}/purchase`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-payment': paymentHeader,
'payment-signature': paymentHeader // Required for verification
},
body: JSON.stringify({ name, owner })
}
);
return retryResponse.json();
}
return response.json();
}
x402 Payment Details​
| Field | Value |
|---|---|
| Network | Base (Chain ID 8453) |
| Asset | USDC (0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913) |
| Receiver | 0xF499102c8707c6501CaAdD2028c6DF1c6C6E813b |
| Facilitator | https://api.cdp.coinbase.com/platform/v2/x402 |
| Amount | Price in USDC Ă— 1,000,000 (6 decimals) |
Pricing Reference​
| Tier | Price | Amount (raw) |
|---|---|---|
| Standard (5+ chars) | $0.97 | 970000 |
| Short (4 chars) | $4.97 | 4970000 |
| Dictionary | $9.97 | 9970000 |
| Ultra Short (3 chars) | $19.97 | 19970000 |
| Premium (1-2 chars) | $97.00 | 97000000 |
Error Responses​
| Status | Code | Description |
|---|---|---|
| 400 | BAD_REQUEST | Missing name or owner |
| 400 | INVALID_ADDRESS | Owner is not valid Ethereum address |
| 402 | INSUFFICIENT_PAYMENT | Payment amount less than required |
| 403 | RESERVED_NAME | Name is reserved and not for sale |
| 409 | NAME_TAKEN | Subname is already registered |
| 429 | RATE_LIMITED | Rate limit exceeded |
| 500 | PURCHASE_ERROR | Internal server error |
Related Endpoints​
- Register (Free) — Try free tier first
- Get Price — Check price before purchasing
- Check Availability — Verify name is available