This guide provides a detailed overview of the registrar crate, covering core concepts, configuration, and practical examples for interacting with supported domain registrar APIs.
The library is designed around a central pattern: a main client for each registrar that acts as an entry point for creating more specialized, "scoped" clients.
You begin by instantiating a main client for the provider you want to use, such as porkbun::Porkbun or name_com::NameDotCom. This object holds your authentication credentials and the shared HTTP client, and it manages the connection pool.
From a main client instance, you can create temporary clients that are scoped to a specific resource, typically a domain name. This is the primary way to interact with the API. This pattern ensures that operations are always performed on the correct resource and provides a highly ergonomic API.
For example, to manage DNS records for "example.com", you would first get a scoped DNS client:
let dns_client = main_client.dns("example.com");
// Now `dns_client` can be used to list, create, or delete records for example.comHere are minimal, runnable examples to get you started quickly.
This example authenticates with the Porkbun API, tests the connection using ping, and then retrieves all DNS records for a specific domain.
use registrar::porkbun::Porkbun;
use registrar::Error;
#[tokio::main]
async fn main() -> Result<(), Error> {
// Load credentials from environment variables or a config file
let apikey = std::env::var("PORKBUN_API_KEY").expect("PORKBUN_API_KEY not set");
let secret = std::env::var("PORKBUN_SECRET_KEY").expect("PORKBUN_SECRET_KEY not set");
let domain = "example.com";
// 1. Create the main Porkbun client
let client = Porkbun::new(apikey, secret);
// 2. Test authentication and connectivity
let ping_response = client.ping().await?;
println!("Successfully connected to Porkbun. Your IP: {}", ping_response.your_ip);
// 3. Get a scoped client for the domain's DNS records
let dns_client = client.dns(domain);
// 4. Perform an action with the scoped client
let records = dns_client.retrieve_all_records().await?;
println!("Found {} DNS records for {}", records.len(), domain);
for record in records {
println!(" - [{}] {} -> {}", record.r#type, record.name, record.content);
}
Ok(())
}This example connects to the Name.com development (sandbox) environment, tests the connection, and then lists all domains in the account.
use registrar::name_com::NameDotCom;
use registrar::Error;
#[tokio::main]
async fn main() -> Result<(), Error> {
// Load credentials for the development environment
let username = std::env::var("NAMECOM_DEV_USERNAME").expect("NAMECOM_DEV_USERNAME not set");
let token = std::env::var("NAMECOM_DEV_TOKEN").expect("NAMECOM_DEV_TOKEN not set");
// 1. Create the main Name.com client for the dev environment
let client = NameDotCom::new_dev(username, token);
// 2. Test authentication and connectivity
let hello_response = client.hello().await?;
println!("Successfully connected to Name.com. Logged in as: {}", hello_response.username);
// 3. Get a scoped client for general domain actions
let domains_client = client.domains();
// 4. Perform an action
let domains = domains_client.list().await?;
println!("Found {} domains in the account.", domains.len());
for domain in domains {
println!(" - {} (Expires: {})", domain.domain_name, domain.expire_date);
}
Ok(())
}The entry point for the Porkbun API.
Methods:
Porkbun::new(apikey: String, secretapikey: String) -> Self- Creates a new client for the production API.
ping(&self) -> Result<PingResponse>- Tests authentication and connectivity.
get_pricing(&self) -> Result<PricingResponse>- Retrieves pricing for all TLDs.
domain<'a>(&'a self, domain: &'a str) -> domain::Domain<'a>- Gets a scoped client for domain-level actions.
dns<'a>(&'a self, domain: &'a str) -> dns::Dns<'a>- Gets a scoped client for DNS record management.
ssl<'a>(&'a self, domain: &'a str) -> ssl::Ssl<'a>- Gets a scoped client for SSL bundle retrieval.
Manages nameservers, URL forwarding, and glue records for a specific domain.
Common Methods:
update_nameservers(&self, nameservers: &[&str]) -> Result<StatusResponse>- Updates the domain's nameservers.
get_url_forwarding(&self) -> Result<Vec<UrlForwardRecord>>- Retrieves all URL forwarding records.
create_glue_record(&self, subdomain: &str, ips: &[IpAddr]) -> Result<StatusResponse>- Creates a new glue record (vanity nameserver).
list_all(&self, include_labels: bool) -> Result<Vec<DomainInfo>>- Retrieves all domains in the account.
Manages DNS and DNSSEC records for a specific domain.
Common Methods:
create_record(&self, options: DnsRecordCreateOptions<'_>) -> Result<DnsRecordCreateResponse>- Creates a new DNS record.
retrieve_all_records(&self) -> Result<Vec<DnsRecord>>- Retrieves all DNS records for the domain.
delete_record_by_id(&self, record_id: u64) -> Result<StatusResponse>- Deletes a DNS record by its ID.
get_dnssec_records(&self) -> Result<HashMap<String, DnssecRecord>>- Retrieves all DNSSEC records.
The entry point for the Name.com Core API.
Methods:
NameDotCom::new(username: String, token: String) -> Self- Creates a new client for the production API.
NameDotCom::new_dev(username: String, token: String) -> Self- Creates a new client for the development (sandbox) API.
hello(&self) -> Result<Hello>- Tests authentication and connectivity.
domains<'a>(&'a self) -> domain::DomainsClient<'a>- Gets a client for account-level domain actions.
dns<'a>(&'a self, domain_name: &'a str) -> dns::DnsClient<'a>- Gets a scoped client for DNS/DNSSEC management.
url_forwarding<'a>(&'a self, domain_name: &'a str) -> url_forwarding::UrlForwardingClient<'a>- Gets a scoped client for URL forwarding.
vanity_ns<'a>(&'a self, domain_name: &'a str) -> vanity_ns::VanityNameserverClient<'a>- Gets a scoped client for vanity nameservers.
Manages domain registration, listing, and configuration.
Common Methods:
domains().list(&self) -> Result<Vec<Domain>>- Retrieves all domains in the account.
domains().create(&self, domain_name: &str) -> Result<CreateDomainResponse>- Registers a new domain.
domains().domain("example.com").get(&self) -> Result<Domain>- Retrieves detailed information for a specific domain.
domains().domain("example.com").update(&self, payload: UpdateDomainPayload) -> Result<Domain>- Updates a domain's lock, privacy, or autorenew status.
domains().domain("example.com").set_nameservers(&self, nameservers: &[&str]) -> Result<Domain>- Sets the nameservers for a specific domain.
Manages DNS and DNSSEC records for a specific domain.
Common Methods:
create_record(&self, payload: DnsRecordPayload<'_>) -> Result<DnsRecord>- Creates a new DNS record.
list_records(&self) -> Result<Vec<DnsRecord>>- Retrieves all DNS records for the domain.
delete_record(&self, record_id: i32) -> Result<()>- Deletes a DNS record by its ID.
list_dnssec(&self) -> Result<Vec<DnssecRecord>>- Retrieves all DNSSEC records.
All fallible operations in the crate return a registrar::Result<T>, which is an alias for std::result::Result<T, registrar::Error>.
The primary error type is the registrar::Error enum, which has three variants:
Error::Http(reqwest::Error): A lower-level error occurred during the network request itself (e.g., connection refused, DNS lookup failure, invalid TLS certificate).Error::Json(serde_json::Error): An error occurred while serializing the request data to JSON or deserializing the response body from JSON. This often indicates a malformed response from the API or a bug in the library's data structures.Error::Api(String): The API server successfully received and processed the request but returned a logical error (e.g., "Invalid API Key", "Domain not available", "Unknown API endpoint"). TheStringcontains the descriptive error message from the provider.