Developer integration

Human-readable Arc recipients in minutes.

Resolve .arc and .circle names through one public, CORS-enabled API. No SDK, API key, or contract ABI is required for the first integration.

Public base URL

https://arcname.services/api/v1
LiveArc TestnetAPI v1
Step 01

Test the endpoint

Start with a known name. The API normalizes case, validates the namespace, and returns the resolved address plus ownership and expiry context when available.

Resolve a nameshell
curl --request GET \
  --url https://arcname.services/api/v1/resolve/name/alice.arc \
  --header 'Accept: application/json'

Expected success

{
  "status": "ok",
  "name": "alice.arc",
  "address": "0x...",
  "owner": "0x...",
  "expiry": 1800000000,
  "source": "subgraph"
}
Step 02

Add a typed client

Keep the adapter behind one function so your application has a single place for normalization, error handling, caching, and future version changes.

arcns.tsTypeScript
type ArcNSResolution =
  | { status: "ok"; name: string; address: `0x${string}`; owner: string | null; expiry: number | null; source: "subgraph" | "rpc" }
  | { status: "not_found"; hint: string }
  | { status: "error"; code: string; hint: string };

export async function resolveArcNSName(name: string) {
  const normalized = name.trim().toLowerCase();
  const response = await fetch(
    `https://arcname.services/api/v1/resolve/name/${encodeURIComponent(normalized)}`,
    { headers: { Accept: "application/json" } },
  );
  const result = (await response.json()) as ArcNSResolution;

  if (!response.ok || result.status !== "ok") {
    throw new Error("hint" in result ? result.hint : "ArcNS resolution failed");
  }
  return result;
}
200 / ok

Resolved address returned

200 / not_found

Valid input, no record

400 / error

Malformed name or TLD

503 / error

Upstream temporarily unavailable

Step 03

Build safe recipient UX

Resolve after the user pauses or leaves the input, then show the complete destination address before any signature request. Never replace the address with the name in the final review screen.

RecipientPreview.tsxReact
import { useEffect, useState } from "react";
import { resolveArcNSName } from "./arcns";

export function RecipientPreview({ name }: { name: string }) {
  const [address, setAddress] = useState<string | null>(null);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    let active = true;
    setAddress(null);
    setError(null);
    resolveArcNSName(name)
      .then(result => active && setAddress(result.address))
      .catch(err => active && setError(err.message));
    return () => { active = false; };
  }, [name]);

  if (error) return <p role="alert">{error}</p>;
  if (!address) return <p>Resolving...</p>;
  return <p>{name} → {address}</p>;
}
Payment safety: cache only briefly, re-resolve immediately before transaction construction, and display the final address that will receive funds.
Step 04

Add reverse names

Use reverse resolution to decorate wallet addresses in activity feeds and account menus. ArcNS only returns a primary name after forward confirmation, preventing a name from claiming an unrelated address.

Reverse lookupTypeScript
const address = "0x1234...";
const response = await fetch(
  `https://arcname.services/api/v1/resolve/address/${address}`,
);
const result = await response.json();

// A reverse name is returned only after forward confirmation.
if (response.ok && result.status === "ok") {
  console.log(result.name);
}
Step 05

Harden production

For backend-heavy applications, proxy and cache the public adapter so you control retries, observability, and your user-facing availability policy.

Server-side proxyNext.js
// app/api/recipient/[name]/route.ts
import { NextResponse } from "next/server";

export async function GET(_: Request, { params }: { params: { name: string } }) {
  const upstream = await fetch(
    `https://arcname.services/api/v1/resolve/name/${encodeURIComponent(params.name)}`,
    { next: { revalidate: 30 } },
  );
  const body = await upstream.json();
  return NextResponse.json(body, { status: upstream.status });
}
Validate .arc or .circle before calling the API
Use AbortController and a short timeout
Respect Cache-Control and retry only safe GET requests
Treat 200 not_found differently from 503 unavailable
Show the final 0x address before transfers
Keep a direct-address fallback available
Monitor latency, error rate, and resolution source
Pin API v1 and test error schemas in CI