Dial x402

Getting Started

Set up your agent to use Dial x402 telephony APIs in under 5 minutes.

Getting Started

Get your AI agent sending SMS and querying phone data in under 5 minutes.

Prerequisites

  • Node.js 18+
  • An EVM wallet with USDC on Base (mainnet) or Base Sepolia (testnet)
  • That's it. No signup, no API keys, no accounts.

Install the SDK

npm install @dial/api @x402/fetch @x402/core @x402/evm viem

Set Up x402 Payment

Important: the wallet's chain MUST match the network the API advertises in its accepts (controlled by X402_EVM_NETWORK / X402_EVM_NETWORKS on the server). Mismatched chains yield Provided chainId "X" must match the active chainId "Y" from viem when signing. For the hosted API at x402.dial.wtf, use base (mainnet); use baseSepolia against a Sepolia-configured deployment.

import { privateKeyToAccount } from "viem/accounts";
import { createWalletClient, http } from "viem";
import { base, baseSepolia } from "viem/chains";
import { wrapFetchWithPayment } from "@x402/fetch";
import { x402Client } from "@x402/core/client";
import { ExactEvmScheme } from "@x402/evm/exact/client";
import { toClientEvmSigner } from "@x402/evm";

// Pick the chain the target API expects (eip155:8453 = base, eip155:84532 = baseSepolia).
const chain = process.env.X402_EVM_NETWORK === "eip155:84532" ? baseSepolia : base;

// Your agent's wallet
const account = privateKeyToAccount("0xYOUR_PRIVATE_KEY");
const walletClient = createWalletClient({
  account,
  chain,
  transport: http(),
});

// Create x402 payment client
const signer = toClientEvmSigner(walletClient);
const client = new x402Client();
client.register("eip155:*", new ExactEvmScheme(signer));
const paidFetch = wrapFetchWithPayment(fetch, client);

Create a Dial Client

import { DialClient } from "@dial/api";

const dial = new DialClient({
  baseUrl: "https://x402.dial.wtf",
  x402Fetch: paidFetch, // x402 payments handled automatically for paid actions
});

Send Your First SMS

const result = await dial.sms.send({
  to: "+1234567890",
  message: "Hello from my AI agent!",
});

console.log(result);
// { success: true, message: "SMS sent", provider: "dial", messageIds: [12345] }

Look Up a Phone Number

const lookup = await dial.lookup.phone({
  phoneNumber: "+1234567890",
  fields: ["line_type_intelligence", "caller_name"],
});

console.log(lookup);
// { success: true, phoneNumber: "+1234567890", valid: true, data: { ... } }

Search Breach Data

const breaches = await dial.dehashed.search({
  query: "email:target@example.com",
});

console.log(breaches);
// { success: true, total: 42, entries: [...] }

Using cURL (No SDK)

You can call endpoints directly. Without a payment header you get 402 Payment Required. In x402 v2 the priced offer is in the PAYMENT-REQUIRED response header (the JSON body is often {}), so use -i to print status + headers:

curl -i -sS -X POST "https://x402.dial.wtf/api/v1/sms/send" \
  -H "Content-Type: application/json" \
  -d '{"to":"+1234567890","message":"Hello"}'

Decode the header value (base64) to inspect networks and amounts, e.g. echo '<paste>' | base64 -d | jq .

Sign the payment authorization with your wallet, then resubmit with the PAYMENT-SIGNATURE header (same as @x402/fetch sets automatically).

Alternative: Credits (Bearer Token)

If you prefer not to pay per-request, buy credits via x402 once and use a Bearer token. The "Bearer token" here is your Privy access token — see the dedicated Bearer Token page for how to grab one from the dashboard or via the Privy SDK.

// Buy 100 credits for $0.10 (requires x402 payment + Bearer token)
await dial.credits.topUp();

// Use credits for subsequent calls (no x402 needed).
// Get `bearerToken` from /dashboard/billing → "API Token" → Reveal,
// or call `getAccessToken()` from `@privy-io/react-auth`.
const dial2 = new DialClient({
  baseUrl: "https://x402.dial.wtf",
  bearerToken: "<your-privy-access-token>",
});

await dial2.messages.sendWithCredits({
  to: "+1234567890",
  body: "Paid with credits!",
});

Generate a Wallet

Need a fresh wallet for your agent?

import { generatePrivateKey, privateKeyToAccount } from "viem/accounts";

const privateKey = generatePrivateKey();
const account = privateKeyToAccount(privateKey);

console.log("Address:", account.address);
console.log("Private Key:", privateKey);
// Fund with USDC on Base Sepolia via faucet for testing

Next Steps

On this page