Docs
BlogHomeStart building

Buy a Domain

Register a domain on Totalum and connect it in one step.


A domain bought on Totalum is registered in your name, paid with the card saved on your Totalum account (not with credits), renewed every year automatically (the renewal is charged 30 days before the expiry and retried 21 and 15 days before; if it is still unpaid 14 days before the expiry, automatic renewal is switched off and you are told by e-mail — renew by hand until the expiry), and connected to a project without any DNS work. Buying domains needs the Starter plan or above; a plan holds up to 3 (Starter), 10 (Builder), 50 (Professional) or unlimited (Enterprise) domains, and at most 5 can be bought a day. Prices are in your billing currency.

These endpoints are account-level (no project in the path). Purchases, renewals, contacts and transfers are the account owner's.

Before buying, create the registrant contact (the domain's legal owner, published in WHOIS with privacy on): Create Registrant Contact. The registrant must verify their e-mail address by the deadline shown in verification.verifyBy, or the domain is suspended until they do.

#Search Domains

GET/api/v1/vcaas/domains/searchapi-keyFree

Which names are available, and their price.

Query parameters

FieldTypeRequiredDescription
qstringYesA name (barbershop) or a full domain (barbershop.com)
tldsstringNoComma-separated extensions to check (com,io); default: every extension sold

Response fields

FieldTypeDescription
data.results[].domainstringThe domain
data.results[].availablebooleanCan be bought now
data.results[].premiumbooleanAlways false (premium names are not offered)
data.results[].pricenumberFirst-year price
data.results[].renewalPricenumberYearly renewal price. It can be much higher than price (a registry's first-year promotion), so show both: "€3.59 first year, then €91.19/year"
data.results[].currencystringeur or usd

Example request

curl -H "api-key: tlm_sk_your_key" \
  "https://builder-api.totalum.app/api/v1/vcaas/domains/search?q=barbershop&tlds=com,io"
Success · 200 OK
json
{ "errors": null, "data": { "results": [{ "domain": "barbershop.io", "available": true, "premium": false, "price": 52.8, "renewalPrice": 52.8, "currency": "eur" }, { "domain": "barbershop.com", "available": false, "premium": false, "price": 0, "renewalPrice": 0, "currency": "eur" }] } }

Error codes

CodeHTTPMeaning
VALIDATION_ERROR400q is missing
End of Search DomainsNext endpointGETList TLDs

#List TLDs

GET/api/v1/vcaas/domains/tldsapi-keyFree

The extensions sold and their prices.

Response fields

FieldTypeDescription
data.tlds[].tldstringExtension (com)
data.tlds[].pricenumberFirst-year price
data.tlds[].renewalPricenumberYearly renewal
data.tlds[].currencystringeur or usd
data.tlds[].requirementsbooleanThe registry asks for extra registrant data

Example request

curl -H "api-key: tlm_sk_your_key" \
  https://builder-api.totalum.app/api/v1/vcaas/domains/tlds
Success · 200 OK
json
{ "errors": null, "data": { "tlds": [{ "tld": "com", "price": 14.4, "renewalPrice": 14.4, "currency": "usd", "requirements": false }] } }

#Buy Domain

POST/api/v1/vcaas/domains/purchaseapi-keyCard payment (not credits)

Charge the saved card and register the domain. If the registration fails, the payment is refunded at once. Send an Idempotency-Key header so a retried request never buys twice (a retry of a domain you already hold returns it without a new charge). With projectId, the domain is attached to that project in the same call.

Body parameters

FieldTypeRequiredDescription
domainstringYesThe domain to buy
contactIdstringYesThe registrant contact
yearsnumberNoAlways 1: a domain is bought for one year, then renews every year. Any other value is refused (400 VALIDATION_ERROR)
projectIdstringNoAttach to this project after the purchase
canonicalHoststringNoWhere the site answers: "www" (default), "app" or any DNS label (letters, digits, inner hyphens) — the site is served at <label>.<domain> and the bare domain redirects there (301, path and query kept) — or "apex" (the bare domain itself). Refused with 400 VALIDATION_ERROR before any charge when it is not a valid label
expectedPricenumberNoThe price you showed: if the live price differs, nothing is bought (409 PRICE_CHANGED)

Response fields

FieldTypeDescription
data.domain.idstringDomain id
data.domain.domainstringThe domain
data.domain.statusstring"active"
data.domain.registeredAtstringISO 8601
data.domain.expiresAtstringISO 8601
data.domain.autoRenewbooleantrue
data.domain.pricePaidnumberWhat was charged
data.domain.renewalPriceEstimatenumberThe expected yearly renewal
data.domain.attachedProjectIdstring | undefinedThe project it serves
data.domain.contactVerificationPendingbooleanThe registrant still has to verify their e-mail
data.warningsobject[] | undefined{ code } — e.g. the attach did not happen (attach it with Attach Domain)

Example request

curl -X POST \
  -H "api-key: tlm_sk_your_key" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 7d1e4c2a-buy-barbershop-io" \
  -d '{"domain":"barbershop.io","contactId":"ct_01k6y2","projectId":"barber-bookings","expectedPrice":52.8}' \
  https://builder-api.totalum.app/api/v1/vcaas/domains/purchase
Success · 201 Created
json
{ "errors": null, "data": { "domain": { "id": "dom_01k6y3", "domain": "barbershop.io", "status": "active", "registeredAt": "2026-10-08T12:30:00.000Z", "expiresAt": "2027-10-08T12:30:00.000Z", "autoRenew": true, "pricePaid": 52.8, "renewalPriceEstimate": 52.8, "attachedProjectId": "barber-bookings", "contactVerificationPending": true } } }

Error codes

CodeHTTPMeaning
VALIDATION_ERROR400domain or contactId is missing
TLD_NOT_ALLOWED400The extension is not sold
DOMAIN_PREMIUM_NOT_ALLOWED400Premium names are not sold
NO_PAYMENT_METHOD402Add a card to your Totalum account first
PAYMENT_FAILED402The card was declined (errorDetails.declineCode)
FEATURE_DISABLED403Buying domains is not available yet on your account
PLAN_REQUIRED403Needs the Starter plan or above
DOMAIN_LIMIT_REACHED403Your plan's number of domains is reached
OWNER_ONLY403Only the account owner can buy
DOMAIN_UNAVAILABLE409The domain is taken
PRICE_CHANGED409The price differs from expectedPrice (errorDetails.newPrice)
DOMAIN_CONTACT_REQUIRED422Create the registrant contact first
REGISTRATION_FAILED422The registration was refused; the payment was refunded
RATE_LIMIT_EXCEEDED429More than 5 purchases today

#List Domains

GET/api/v1/vcaas/domainsapi-keyFree

The account's domains.

Response fields

FieldTypeDescription
data.domainsobject[]Domains, with the fields of Get Domain

Example request

curl -H "api-key: tlm_sk_your_key" \
  https://builder-api.totalum.app/api/v1/vcaas/domains
Success · 200 OK
json
{ "errors": null, "data": { "domains": [{ "id": "dom_01k6y3", "domain": "barbershop.io", "status": "active", "registeredAt": "2026-10-08T12:30:00.000Z", "expiresAt": "2027-10-08T12:30:00.000Z", "autoRenew": true, "renewal": { "status": "scheduled", "nextChargeAt": "2027-09-08T12:30:00.000Z", "attempts": [] }, "pricing": { "pricePaid": 52.8, "currency": "eur", "renewalPriceEstimate": 52.8 }, "privacy": true, "locked": true, "contactId": "ct_01k6y2", "contactVerified": false, "nameservers": ["ns1.totalum-dns.com"], "dnsManaged": true, "attachedProjectId": "barber-bookings", "canonicalHost": "www", "exportAvailableAt": "2026-12-07T12:30:00.000Z", "verification": { "contactVerificationPending": true, "verifyBy": "2026-10-23T12:30:00.000Z" } }] } }

#Get Domain

GET/api/v1/vcaas/domains/:domainIdapi-keyFree

One domain.

Path parameters

ParameterTypeDescription
domainIdstringThe domain id

Response fields

FieldTypeDescription
data.idstringDomain id
data.domainstringThe domain
data.statusstring"active", "expired_grace", "expired", "export_pending", "transferred_out", "external_dns" or "suspended_verification"
data.registeredAtstringISO 8601
data.expiresAtstringISO 8601
data.autoRenewbooleanRenews automatically
data.renewalobject{ status: "scheduled" | "charging" | "renewed" | "cancelled", nextChargeAt, attempts[], lastRenewedAt?, cancelledAt? }
data.pricingobject{ pricePaid, currency, renewalPriceEstimate }
data.privacybooleanWHOIS privacy
data.lockedbooleanTransfer lock
data.contactIdstringRegistrant contact
data.contactVerifiedbooleanRegistrant e-mail verified
data.nameserversstring[]Nameservers
data.dnsManagedbooleanDNS is managed on Totalum
data.attachedProjectIdstring | undefinedThe project it serves
data.canonicalHoststring | undefined"www" or "apex"
data.exportAvailableAtstringFrom when it can be transferred away (60 days after registration)
data.verificationobject{ contactVerificationPending, verifyBy }

Example request

curl -H "api-key: tlm_sk_your_key" \
  https://builder-api.totalum.app/api/v1/vcaas/domains/dom_01k6y3
Success · 200 OK
json
{ "errors": null, "data": { "id": "dom_01k6y3", "domain": "barbershop.io", "status": "active", "registeredAt": "2026-10-08T12:30:00.000Z", "expiresAt": "2027-10-08T12:30:00.000Z", "autoRenew": true, "renewal": { "status": "scheduled", "nextChargeAt": "2027-09-08T12:30:00.000Z", "attempts": [] }, "pricing": { "pricePaid": 52.8, "currency": "eur", "renewalPriceEstimate": 52.8 }, "privacy": true, "locked": true, "contactId": "ct_01k6y2", "contactVerified": true, "nameservers": ["ns1.totalum-dns.com"], "dnsManaged": true, "attachedProjectId": "barber-bookings", "canonicalHost": "www", "exportAvailableAt": "2026-12-07T12:30:00.000Z", "verification": { "contactVerificationPending": false, "verifyBy": null } } }

Error codes

CodeHTTPMeaning
DOMAIN_NOT_FOUND404No such domain in your account

#Update Domain

PATCH/api/v1/vcaas/domains/:domainIdapi-keyFree

Turn WHOIS privacy or automatic renewal on or off. Owner only.

Path parameters

ParameterTypeDescription
domainIdstringThe domain id

Body parameters

FieldTypeRequiredDescription
privacybooleanNoWHOIS privacy
autoRenewbooleanNoAutomatic yearly renewal

Response fields

FieldTypeDescription
dataobjectThe domain after the change, as in Get Domain

Example request

curl -X PATCH \
  -H "api-key: tlm_sk_your_key" \
  -H "Content-Type: application/json" \
  -d '{"autoRenew":false}' \
  https://builder-api.totalum.app/api/v1/vcaas/domains/dom_01k6y3
Success · 200 OK
json
{ "errors": null, "data": { "id": "dom_01k6y3", "domain": "barbershop.io", "status": "active", "autoRenew": false, "renewal": { "status": "cancelled", "nextChargeAt": null, "attempts": [] } } }

#Renew Domain

POST/api/v1/vcaas/domains/:domainId/renewapi-keyCard payment

Renew now for one year (within 90 days of expiry, or during the grace period after it). Owner only.

Path parameters

ParameterTypeDescription
domainIdstringThe domain id

Response fields

FieldTypeDescription
data.domainobjectThe domain after the renewal
data.orderobject | nullThe renewal order

Example request

curl -X POST -H "api-key: tlm_sk_your_key" \
  https://builder-api.totalum.app/api/v1/vcaas/domains/dom_01k6y3/renew
Success · 200 OK
json
{ "errors": null, "data": { "domain": { "id": "dom_01k6y3", "domain": "barbershop.io", "status": "active", "expiresAt": "2028-10-08T12:30:00.000Z" }, "order": { "kind": "renewal", "status": "completed", "customerPrice": 52.8, "currency": "eur" } } }

Error codes

CodeHTTPMeaning
DOMAIN_NOT_RENEWABLE409Not within 90 days of expiry (errorDetails.expiresAt)
PAYMENT_FAILED402The card was declined
REGISTRATION_FAILED422The renewal was refused; the payment was refunded

#Attach Domain

POST/api/v1/vcaas/domains/:domainId/attachapi-key4 credits (first domain of the project)

Serve a project from this domain; Totalum writes the DNS records itself (and the ones that prove ownership of each address). The project must be published. The site answers at <canonicalHost>.<domain> and the bare domain redirects there (301, path and query kept); follow both addresses with Get Custom Domain.

Change the prefix: call it again with the same projectId and another canonicalHost ({"projectId":"barber-bookings","canonicalHost":"app"}): the site moves to the new address in a few minutes and the old one stops answering. No second fee; the same prefix again changes nothing.

Path parameters

ParameterTypeDescription
domainIdstringThe domain id

Body parameters

FieldTypeRequiredDescription
projectIdstringYesThe project
canonicalHoststringNo"www" (default), "app" or any DNS label, or "apex" — as in Buy Domain

Response fields

FieldTypeDescription
data.domainobjectThe domain, as in Get Domain
data.customDomainobjectThe project's custom domain: { domain, hostnames, status, … }

Example request

curl -X POST \
  -H "api-key: tlm_sk_your_key" \
  -H "Content-Type: application/json" \
  -d '{"projectId":"barber-bookings"}' \
  https://builder-api.totalum.app/api/v1/vcaas/domains/dom_01k6y3/attach
Success · 200 OK
json
{ "errors": null, "data": { "domain": { "id": "dom_01k6y3", "domain": "barbershop.io", "attachedProjectId": "barber-bookings", "canonicalHost": "www" }, "customDomain": { "domain": "barbershop.io", "status": "pending" } } }

Error codes

CodeHTTPMeaning
VALIDATION_ERROR400projectId is missing, or canonicalHost is not "apex" or one DNS label
PROJECT_NOT_FOUND404No such project in your account
NO_DEPLOYMENT404Publish the project first
DOMAIN_ALREADY_ATTACHED409Attached to another project; detach it first
INSUFFICIENT_CREDITS402Not enough credits for the domain fee
PLATFORM_CAPABILITY_QUOTA_REACHED403Custom domains are not included on your plan

#Detach Domain

POST/api/v1/vcaas/domains/:domainId/detachapi-keyFree

Stop serving the project from this domain. The domain stays yours and is not refunded. Its automatic renewal keeps running unless you stop it: to remove the domain for good, detach it and then Update Domain with {"autoRenew":false} — it stays registered to you until expiresAt, then expires. Afterwards the project can attach another domain you bought, buy one with projectId, or connect one you own.

Path parameters

ParameterTypeDescription
domainIdstringThe domain id

Response fields

FieldTypeDescription
dataobjectThe domain, as in Get Domain

Example request

curl -X POST -H "api-key: tlm_sk_your_key" \
  https://builder-api.totalum.app/api/v1/vcaas/domains/dom_01k6y3/detach
Success · 200 OK
json
{ "errors": null, "data": { "id": "dom_01k6y3", "domain": "barbershop.io", "status": "active" } }

#List DNS Records

GET/api/v1/vcaas/domains/:domainId/dns/recordsapi-keyFree

The domain's DNS records. managed: true records serve the attached project and cannot be changed.

Path parameters

ParameterTypeDescription
domainIdstringThe domain id

Response fields

FieldTypeDescription
data.records[].idstringRecord id
data.records[].typestringA, AAAA, CNAME, ALIAS, MX, TXT, SRV or NS
data.records[].hoststringHost ("" = the domain itself)
data.records[].answerstringValue
data.records[].ttlnumberSeconds (≥ 300)
data.records[].prioritynumber | undefinedMX/SRV priority
data.records[].managedbooleanWritten by Totalum for the attached project

Example request

curl -H "api-key: tlm_sk_your_key" \
  https://builder-api.totalum.app/api/v1/vcaas/domains/dom_01k6y3/dns/records
Success · 200 OK
json
{ "errors": null, "data": { "records": [{ "id": "rec_1", "type": "MX", "host": "", "answer": "mx.mailprovider.com", "ttl": 300, "priority": 10, "managed": false }] } }

#Create DNS Record

POST/api/v1/vcaas/domains/:domainId/dns/recordsapi-keyFree

Add a record (for example your e-mail provider's MX and TXT records).

Path parameters

ParameterTypeDescription
domainIdstringThe domain id

Body parameters

FieldTypeRequiredDescription
recordobjectYes{ type, host, answer, ttl, priority? } as in List DNS Records

Response fields

FieldTypeDescription
dataobjectThe record, with id and managed: false

Example request

curl -X POST \
  -H "api-key: tlm_sk_your_key" \
  -H "Content-Type: application/json" \
  -d '{"record":{"type":"TXT","host":"","answer":"v=spf1 include:_spf.mailprovider.com ~all","ttl":300}}' \
  https://builder-api.totalum.app/api/v1/vcaas/domains/dom_01k6y3/dns/records
Success · 201 Created
json
{ "errors": null, "data": { "id": "rec_2", "type": "TXT", "host": "", "answer": "v=spf1 include:_spf.mailprovider.com ~all", "ttl": 300, "managed": false } }

Error codes

CodeHTTPMeaning
DNS_RECORD_CONFLICT400Conflicts with an existing record
DNS_RECORD_LIMIT400The domain already has 200 records
VALIDATION_ERROR400Invalid record

#Update DNS Record

PATCH/api/v1/vcaas/domains/:domainId/dns/records/:recordIdapi-keyFree

Change a record you created.

Path parameters

ParameterTypeDescription
domainIdstringThe domain id
recordIdstringThe record id

Body parameters

FieldTypeRequiredDescription
recordobjectYes{ type, host, answer, ttl, priority? }

Response fields

FieldTypeDescription
dataobjectThe record after the change

Example request

curl -X PATCH \
  -H "api-key: tlm_sk_your_key" \
  -H "Content-Type: application/json" \
  -d '{"record":{"type":"MX","host":"","answer":"mx2.mailprovider.com","ttl":300,"priority":20}}' \
  https://builder-api.totalum.app/api/v1/vcaas/domains/dom_01k6y3/dns/records/rec_1
Success · 200 OK
json
{ "errors": null, "data": { "id": "rec_1", "type": "MX", "host": "", "answer": "mx2.mailprovider.com", "ttl": 300, "priority": 20, "managed": false } }

Error codes

CodeHTTPMeaning
DOMAIN_NOT_FOUND404No such record
DNS_RECORD_MANAGED409The record serves the attached project; detach the domain first

#Delete DNS Record

DELETE/api/v1/vcaas/domains/:domainId/dns/records/:recordIdapi-keyFree

Delete a record you created.

Path parameters

ParameterTypeDescription
domainIdstringThe domain id
recordIdstringThe record id

Response fields

FieldTypeDescription
data.deletedbooleantrue

Example request

curl -X DELETE -H "api-key: tlm_sk_your_key" \
  https://builder-api.totalum.app/api/v1/vcaas/domains/dom_01k6y3/dns/records/rec_2
Success · 200 OK
json
{ "errors": null, "data": { "deleted": true } }

Error codes

CodeHTTPMeaning
DOMAIN_NOT_FOUND404No such record
DNS_RECORD_MANAGED409The record serves the attached project
End of Delete DNS RecordNext endpointGETGet Forwarding

#Get Forwarding

GET/api/v1/vcaas/domains/:domainId/forwardingapi-keyFree

The domain's URL forwarding rules (a host of the domain redirecting to another URL).

Path parameters

ParameterTypeDescription
domainIdstringThe domain id

Response fields

FieldTypeDescription
data.forwarding[].hoststringHost of the domain (shop.barbershop.io)
data.forwarding[].forwardsTostringTarget URL
data.forwarding[].typestring"redirect" (301), "302" or "masked"

Example request

curl -H "api-key: tlm_sk_your_key" \
  https://builder-api.totalum.app/api/v1/vcaas/domains/dom_01k6y3/forwarding
Success · 200 OK
json
{ "errors": null, "data": { "forwarding": [{ "host": "shop.barbershop.io", "forwardsTo": "https://store.example.com", "type": "redirect" }] } }

#Set Forwarding

PUT/api/v1/vcaas/domains/:domainId/forwardingapi-keyFree

Replace the whole set of forwarding rules (up to 50). A host the attached project serves is refused.

Path parameters

ParameterTypeDescription
domainIdstringThe domain id

Body parameters

FieldTypeRequiredDescription
forwardingobject[]Yes{ host, forwardsTo, type }; [] removes every rule

Response fields

FieldTypeDescription
data.forwardingobject[]The rules now in place

Example request

curl -X PUT \
  -H "api-key: tlm_sk_your_key" \
  -H "Content-Type: application/json" \
  -d '{"forwarding":[{"host":"shop.barbershop.io","forwardsTo":"https://store.example.com","type":"redirect"}]}' \
  https://builder-api.totalum.app/api/v1/vcaas/domains/dom_01k6y3/forwarding
Success · 200 OK
json
{ "errors": null, "data": { "forwarding": [{ "host": "shop.barbershop.io", "forwardsTo": "https://store.example.com", "type": "redirect" }] } }

#Get Transfer Code

POST/api/v1/vcaas/domains/:domainId/exportapi-keyFree

Unlock the domain and get its transfer (auth) code, to move it to another registrar. Also e-mailed to the owner. Possible 60 days after registration. Owner only.

Path parameters

ParameterTypeDescription
domainIdstringThe domain id

Response fields

FieldTypeDescription
data.authCodestringThe transfer code

Example request

curl -X POST -H "api-key: tlm_sk_your_key" \
  https://builder-api.totalum.app/api/v1/vcaas/domains/dom_01k6y3/export
Success · 200 OK
json
{ "errors": null, "data": { "authCode": "Xk7#pQ2!mZ9w" } }

Error codes

CodeHTTPMeaning
DOMAIN_TRANSFER_LOCKED423Still inside the 60-day lock (errorDetails.availableAt)
DOMAIN_NOT_RENEWABLE409A renewal charge is in progress; retry shortly
End of Get Transfer CodeNext endpointPOSTCancel Transfer

#Cancel Transfer

POST/api/v1/vcaas/domains/:domainId/export/cancelapi-keyFree

Lock the domain again and cancel a pending transfer. Owner only.

Path parameters

ParameterTypeDescription
domainIdstringThe domain id

Response fields

FieldTypeDescription
dataobjectThe domain, as in Get Domain

Example request

curl -X POST -H "api-key: tlm_sk_your_key" \
  https://builder-api.totalum.app/api/v1/vcaas/domains/dom_01k6y3/export/cancel
Success · 200 OK
json
{ "errors": null, "data": { "id": "dom_01k6y3", "domain": "barbershop.io", "status": "active", "locked": true } }

#List Domain Orders

GET/api/v1/vcaas/domains/:domainId/ordersapi-keyFree

The domain's payments: registration, renewals and refunds.

Path parameters

ParameterTypeDescription
domainIdstringThe domain id

Response fields

FieldTypeDescription
data[].kindstring"registration", "renewal" or "refund"
data[].statusstringOrder status
data[].customerPricenumberAmount
data[].currencystringeur or usd
data[].atstringISO 8601
data[].stripePaymentIntentIdstring | undefinedThe card payment
data[].refundedbooleanThe payment was refunded

Example request

curl -H "api-key: tlm_sk_your_key" \
  https://builder-api.totalum.app/api/v1/vcaas/domains/dom_01k6y3/orders
Success · 200 OK
json
{ "errors": null, "data": [{ "kind": "registration", "status": "completed", "customerPrice": 52.8, "currency": "eur", "at": "2026-10-08T12:30:00.000Z", "stripePaymentIntentId": "pi_3Q…", "refunded": false }] }

#List Registrant Contacts

GET/api/v1/vcaas/domains/contactsapi-keyFree

The account's registrant contacts.

Response fields

FieldTypeDescription
data.contacts[].idstringContact id (for contactId)
data.contacts[].labelstring | undefinedYour label
data.contacts[].contactobjectThe contact data (see Create Registrant Contact)

Example request

curl -H "api-key: tlm_sk_your_key" \
  https://builder-api.totalum.app/api/v1/vcaas/domains/contacts
Success · 200 OK
json
{ "errors": null, "data": { "contacts": [{ "id": "ct_01k6y2", "label": "Main", "contact": { "firstName": "Ana", "lastName": "García", "email": "ana@barbershop.io", "phone": "+34600111222", "address1": "Calle Mayor 1", "city": "Madrid", "zip": "28013", "country": "ES" } }] } }
End of List Registrant ContactsNext endpointPOSTCreate Registrant Contact

#Create Registrant Contact

POST/api/v1/vcaas/domains/contactsapi-keyFree

Create the legal owner data used to register domains. Owner only.

Body parameters

FieldTypeRequiredDescription
labelstringNoUp to 100 characters
contactobjectYesThe registrant
contact.firstNamestringYesFirst name
contact.lastNamestringYesLast name
contact.organizationstringNoCompany
contact.emailstringYesE-mail (must be verified after a purchase, see verification.verifyBy)
contact.phonestringYesInternational format: +, the country calling code and the number, +34644479777. Spaces, dashes, dots and parentheses are accepted and removed, and a leading 00 is read as + (0034 644 47 97 77 is saved as +34644479777)
contact.address1stringYesAddress
contact.address2stringNoAddress, second line
contact.citystringYesCity
contact.statestringNoState or province
contact.zipstringYesPostal code
contact.countrystringYesTwo-letter ISO 3166-1 alpha-2 code (ES, US), any case, saved uppercase. A country name (United States) is refused

Response fields

FieldTypeDescription
data.idstringContact id
data.labelstring | undefinedLabel
data.contactobjectThe contact

Example request

curl -X POST \
  -H "api-key: tlm_sk_your_key" \
  -H "Content-Type: application/json" \
  -d '{"label":"Main","contact":{"firstName":"Ana","lastName":"García","email":"ana@barbershop.io","phone":"+34600111222","address1":"Calle Mayor 1","city":"Madrid","zip":"28013","country":"ES"}}' \
  https://builder-api.totalum.app/api/v1/vcaas/domains/contacts
Success · 201 Created
json
{ "errors": null, "data": { "id": "ct_01k6y2", "label": "Main", "contact": { "firstName": "Ana", "lastName": "García", "email": "ana@barbershop.io", "phone": "+34600111222", "address1": "Calle Mayor 1", "city": "Madrid", "zip": "28013", "country": "ES" } } }

Error codes

CodeHTTPMeaning
VALIDATION_ERROR400A field is missing or invalid; the message names it, e.g. country must be a 2-letter ISO code like ES, US or phone must be in international format like +34644479777 (spaces are removed)
OWNER_ONLY403Only the account owner
End of Create Registrant ContactNext endpointPATCHUpdate Registrant Contact

#Update Registrant Contact

PATCH/api/v1/vcaas/domains/contacts/:contactIdapi-keyFree

Change a contact. Every active domain registered with it is updated; a change of registrant restarts the 60-day transfer lock of those domains.

Path parameters

ParameterTypeDescription
contactIdstringThe contact id

Body parameters

FieldTypeRequiredDescription
labelstringNoLabel
contactobjectYesThe full contact, as in Create Registrant Contact

Response fields

FieldTypeDescription
data.contactobjectThe saved contact
data.warningsobject[]{ code: "DOMAIN_TRANSFER_LOCKED", domains } when domains were re-locked

Example request

curl -X PATCH \
  -H "api-key: tlm_sk_your_key" \
  -H "Content-Type: application/json" \
  -d '{"contact":{"firstName":"Ana","lastName":"García","email":"ana@barbershop.io","phone":"+34600111222","address1":"Calle Mayor 2","city":"Madrid","zip":"28013","country":"ES"}}' \
  https://builder-api.totalum.app/api/v1/vcaas/domains/contacts/ct_01k6y2
Success · 200 OK
json
{ "errors": null, "data": { "contact": { "id": "ct_01k6y2", "label": "Main" }, "warnings": [] } }

#Resend Registrant Verification

POST/api/v1/vcaas/domains/contacts/:contactId/resend-verificationapi-keyFree

Send the registrant's verification e-mail again.

Path parameters

ParameterTypeDescription
contactIdstringThe contact id

Response fields

FieldTypeDescription
data.sentnumberVerification e-mails sent (0 when nothing is pending)

Example request

curl -X POST -H "api-key: tlm_sk_your_key" \
  https://builder-api.totalum.app/api/v1/vcaas/domains/contacts/ct_01k6y2/resend-verification
Success · 200 OK
json
{ "errors": null, "data": { "sent": 1 } }
End of Resend Registrant Verification Back to top