ans://v1.0.0.my-agent.example.com) with X.509 identity certificates and an append-only transparency log, so any party can resolve an agent name and confirm who is on the other end.
ANS gives an agent a name and a verifiable identity. Dynamic gives that same agent a wallet that can sign and transact. Combined, you hand counterparties a single human-readable identifier they can use to verify who an agent is and which wallet it pays from — before any onchain action happens.
This page shows the end-to-end pattern: create a Dynamic server wallet, register the wallet under an ANS name, then resolve and verify other ANS-named agents before paying or trusting them. Code samples are provided for Node, Python, and Rust — pick the SDK that matches your stack.
The ANS request/response shapes below follow the v2 RA API and the transparency-log API from the GoDaddy ANS reference implementation —
spec/api-spec-v2.yaml and spec/api-spec-tl-v2.yaml. The flow here was validated end-to-end against that implementation run locally. There is no official Node or Python ANS SDK yet, so those samples call the REST API directly; official SDKs exist for Rust, Go, and Java.Why combine them
For agent-to-agent flows — especially anything that touches money — pairing the two lets the recipient resolve an
ans:// name, validate the agent’s certificate against the transparency log, and only then accept its onchain signature as authoritative.
Prerequisites
- A Dynamic Environment ID and API token from the Dynamic Dashboard
- Access to an ANS Registration Authority (RA) and a bearer token for it. Obtain one from ansinfo.ai, or run the reference RA locally (see the note below).
- A domain you control — ANS performs DNS-based ownership verification before issuing a certificate
- Runtime for the SDK you choose: Node.js 22+, Python 3.10+, or Rust 1.76+
- Node
- Python
- Rust
.env
Auth is a bearer token, sent as
Authorization: Bearer <token> (the RA also accepts GoDaddy’s Authorization: sso-key <apiKey>:<apiSecret> form) — there is no X-API-Key header. To try the flow locally, clone github.com/godaddy/ans, run docker compose up --build -d followed by make docker-compose-bootstrap, then set ANS_API_BASE=http://localhost:18080/v2, ANS_TL_BASE=http://localhost:18081, and ANS_API_TOKEN=ans-dev-key-change-me.Step 1: Create a Dynamic server wallet for the agent
This wallet is what the agent will use to sign onchain payments. Persist the returned key shares in your secrets manager.- Node
- Python
- Rust
Step 2: Publish an agent card that includes the wallet
The Agent Card is the off-chain metadata document an ANS endpoint points at. This is where the Dynamic wallet and the ANS identity meet: the card declares which onchain account this named agent pays from, so any counterparty resolving the ANS name can decide whether to accept it before transacting.https://my-agent.example.com/.well-known/agent-card.json
metaDataUrl, alongside a metaDataHash that pins its contents:
Step 3: Generate the X.509 CSRs
ANS issues X.509 certificates from Certificate Signing Requests. Use a separate keypair from the Dynamic wallet — the Dynamic wallet key signs onchain transactions, while the X.509 identity key signs mTLS handshakes between agents. The link between the two identities is the wallet address you publish in the agent card (Step 2). Two important requirements the RA enforces:- Keys must be EC P-256 (ECDSA
secp256r1). RSA CSRs are rejected. - The identity CSR’s Subject Alternative Name must be a URI equal to the agent’s
ans://name. The optional server (TLS) CSR’s SAN is the agent host FQDN.
- Node
- Python
- Rust
Step 4: Register the agent and activate it
Registration is a multi-step, asynchronous flow:POST {ANS_API_BASE}/ans/agentsreturns202 PENDING_VALIDATIONwith anagentId. All later calls address the agent by thatagentId(a UUID), not by name.POST .../verify-acmeproves domain control and issues the identity + server certificates →PENDING_DNS.POST .../verify-dnsconfirms the published DNS records →ACTIVE.
- Node
- Python
- Rust
If the RA has no server CA configured it rejects
serverCsrPEM (and registration requires exactly one of serverCsrPEM / serverCertificatePEM). Either point it at a server CA, or bring your own server certificate via serverCertificatePEM + serverCertificateChainPEM. Field names and status codes follow spec/api-spec-v2.yaml.Step 5: Resolve and verify a counterparty agent
Before paying or trusting another agent, verify its identity against the transparency log and pin its agent card to that log. Resolving the agent’sans:// name via DNS yields its transparency-log endpoint and agentId. You fetch the badge — which carries the agent’s status and the metaDataHash the log sealed at registration — and the SCITT receipt, verify the receipt’s COSE signature and Merkle inclusion proof against the log’s published /root-keys, then fetch the agent card and confirm its SHA-256 matches that sealed hash. Only a card whose hash matches the attested value may be trusted for the wallet address — that hash comparison is what actually binds the wallet to the verified identity. (Hash the exact bytes the card is served as; serve it as a fixed document so the digest is stable.)
- Node
- Python
- Rust
End-to-end: a paid call between two named agents
A common shape for production agent-to-agent commerce:- Buyer agent has a Dynamic server wallet and an
ans://buyer.example.comregistration. - Seller agent has its own Dynamic wallet and
ans://seller.example.com. - Buyer resolves
seller.example.com, validates the transparency-log receipt, fetches the seller’s agent card, and confirms the published wallet matches thepayTofield in the seller’s 402 response. - Buyer signs the 402 payment via its Dynamic wallet and retries the request.
- Both sides hold a verifiable record of who paid whom, anchored in ANS.
Lifecycle: renewal and revocation
ANS certificates have a finite lifetime. Plan for renewal — submit a new CSR to the certificate-renewal endpoints (.../certificates/server/renewal) before expiry; the same wallet stays in the agent’s metadata.
If a wallet is compromised or you retire the agent, revoke the ANS record so resolvers stop trusting it. Revoke by agentId, and pass a reason from the revocation-reason enum (KEY_COMPROMISE, CESSATION_OF_OPERATION, AFFILIATION_CHANGED, SUPERSEDED, CERTIFICATE_HOLD, PRIVILEGE_WITHDRAWN, AA_COMPROMISE):
- Node
- Python
- Rust
Additional Resources
- GoDaddy ANS developer portal
- GoDaddy ANS reference implementation — registry + transparency log in Go, with the OpenAPI specs under
spec/(api-spec-v2.yaml,api-spec-tl-v2.yaml) - ANS OpenAPI specification — the hosted, human-readable contract
- Official ANS SDKs: Rust · Go · Java
- Agent Name Registry (ansinfo.ai) — obtain RA access
- Agent Payments — pay 402-protected APIs from the same wallet
- Server wallet setup — provision the wallet ANS binds to: Node · Python · Rust