Get started
Domains and DNS
tsmartSend sends only from domains your company has verified. Verification has two parts: proving that you own the domain, then publishing SPF and DKIM so receiving servers accept mail we send in your name.
Overview
- Add the domain (console or
POST /domains). - Publish the ownership TXT record and verify. The domain is then created on our mail server with a DKIM key.
- Publish the SPF and DKIM records (and, recommended, DMARC) and check again.
- When SPF and DKIM are both in place, the domain's status is
verifiedand it can send.
A domain that is already used for mailboxes on tsmart.ai has gone through steps 1 and 2; it only needs SPF and DKIM.
You can verify a subdomain (for example notify.acme.com) and send application mail from it, keeping it
apart from the mail your people send.
1. Add the domain
In the console open Account → Domains → Manage domains, or call the API with a full-access key whose creator has the Domains privilege:
curl -X POST https://send.tsmart.ai/domains \
-H "Authorization: Bearer $TSMART_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "acme.com"}' {
"object": "domain",
"id": "b7c1e0a2-5d0f-4a51-9a64-0f3c2a7d9e11",
"name": "acme.com",
"status": "not_started",
"created_at": "2026-10-12 09:30:11.412000+00",
"region": "eu-central",
"capabilities": { "sending": "disabled", "receiving": "disabled" },
"open_tracking": false,
"click_tracking": false,
"records": [
{
"record": "Ownership",
"name": "_tsmart-verify.acme.com",
"type": "TXT",
"ttl": "Auto",
"status": "pending",
"value": "tsmart-verify=Vb3kQ9mXf2LpT7wRzA1c_8nE"
}
]
} const { data, error } = await tsmart.domains.create({ name: "acme.com" }); domain = client.domains.create({"name": "acme.com"}) Rules when adding a domain:
- A domain can belong to only one company. A name that is already registered is refused.
- Public mailbox providers and reserved example domains cannot be added.
- A company can have at most 10 domains waiting for ownership verification, and its plan may limit the total.
- A domain whose ownership is not proven within 7 days of when your company first added it is removed; add it again to get a new token. Deleting the domain and adding it again does not restart the 7 days.
- While another company's unproven claim holds a domain, adding it is refused with the date from which it can be added if that company does not prove ownership. A company whose claim lapsed while another company was waiting for the domain cannot add it again for the next 7 days, so the waiting company can take it.
2. Prove ownership
Publish one TXT record with the token from the console or from records:
| Name | Type | Value |
|---|---|---|
_tsmart-verify.acme.com | TXT | tsmart-verify=<token> |
Then click Verify on the domain page, or call POST /domains/{id}/verify. If
the record is not found yet, the API answers 422 validation_error with
The TXT record _tsmart-verify.acme.com was not found yet. The check asks the domain's own name servers, so
a record you just published is usually seen at once.
curl -X POST https://send.tsmart.ai/domains/b7c1e0a2-5d0f-4a51-9a64-0f3c2a7d9e11/verify \
-H "Authorization: Bearer $TSMART_API_KEY"
When ownership is proven, the domain is created on our mail server together with its DKIM key, and the DNS records
below are listed. You can delete the _tsmart-verify record afterwards.
If the company owner has connected a supported DNS provider account in the console, the domain page can publish the ownership record and the missing records for you.
3. Publish the sending records
The console's domain page and GET /domains/{id} list the exact values for your domain. SPF and
DKIM are required; DMARC is recommended.
SPF
SPF tells receiving servers that our mail server may send for your domain. It is a TXT record on the domain itself.
| Your domain today | Publish at acme.com (TXT) |
|---|---|
| No SPF record | v=spf1 ip4:91.99.133.27 ~all |
An SPF record, for example v=spf1 include:_spf.example.net ~all | v=spf1 ip4:91.99.133.27 include:_spf.example.net ~all |
-
Keep a single SPF record. If you already have one, add
ip4:91.99.133.27right afterv=spf1and keep every other mechanism and the ending (~allor-all) as they are. The console suggests exactly this merged value. -
The check passes when the record itself contains
ip4:91.99.133.27ora:mail.tsmart.ai. It does not followinclude:mechanisms, so an include that happens to cover the address does not count. - An
ip4:mechanism needs no DNS lookup, so it does not use up SPF's limit of 10 lookups.
DKIM
Every email is signed with a 2048-bit DKIM key that belongs to your domain. The public key is published as a TXT record under the domain's selector.
| Name | Type | Value |
|---|---|---|
tsYYMM._domainkey.acme.com, for example ts2610._domainkey.acme.com | TXT | v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA… |
-
The selector is
tsfollowed by the year and month the domain was added (ts2610for October 2026). Always use the selector and value the console or the API shows for your domain; it changes if the key is rotated. - The key is created when ownership is proven, so the DKIM value appears only after that step. For a few moments it can show as still being generated.
-
The check passes when the published record contains the key (the
p=value); spaces are ignored.
DMARC (recommended)
DMARC tells receivers what to do with mail that fails SPF and DKIM, and where to send reports. It is not required to send, but large mailbox providers increasingly expect it.
| Name | Type | Value |
|---|---|---|
_dmarc.acme.com | TXT | v=DMARC1; p=none; rua=mailto:reports@system.tsmart.ai; fo=1 |
With this record the aggregate reports arrive at tsmart.ai and are shown in the console under
Reporting → DMARC reports. If your domain already has a DMARC record, the console keeps it as it is; do not
publish a second one. Start with p=none, read the reports, then move to p=quarantine or
p=reject once all your legitimate mail passes.
MX (optional, for incoming mail)
tsmartSend does not need an MX record. Publish acme.com MX 10 mail.tsmart.ai. only when the domain's
mailboxes move to tsmart.ai: changing MX moves all incoming mail for the domain, so do it on the day you switch. Replies
to your emails go to the from or reply_to address wherever its mailbox is hosted.
Other records for mailboxes (optional)
The console also lists records that help mail apps and other mail servers when the domain's mailboxes are on tsmart.ai. None of them affects tsmartSend.
| Name | Type | Value | Purpose |
|---|---|---|---|
autodiscover.acme.com | CNAME | mail.tsmart.ai. | Mail app set-up |
autoconfig.acme.com | CNAME | mail.tsmart.ai. | Mail app set-up |
_submissions._tcp.acme.com | SRV | 0 1 465 mail.tsmart.ai. | SMTP discovery |
_imaps._tcp.acme.com | SRV | 0 1 993 mail.tsmart.ai. | IMAP discovery |
mta-sts.acme.com | CNAME | mail.tsmart.ai. | MTA-STS policy host |
_mta-sts.acme.com | TXT | v=STSv1; id=<id from the console> | MTA-STS policy id (listed once the policy is active) |
_smtp._tls.acme.com | TXT | v=TLSRPTv1; rua=mailto:reports@system.tsmart.ai | TLS reports |
4. Check the records
After publishing, click Check DNS records on the domain page or call
POST /domains/{id}/verify again. Once ownership is proven, every call re-reads the records and
stores the result; GET /domains/{id} then shows it.
{
"object": "domain",
"id": "b7c1e0a2-5d0f-4a51-9a64-0f3c2a7d9e11",
"name": "acme.com",
"status": "verified",
"capabilities": { "sending": "enabled", "receiving": "disabled" },
"records": [
{ "record": "SPF", "name": "acme.com", "type": "TXT", "ttl": "Auto", "status": "verified",
"value": "v=spf1 ip4:91.99.133.27 ~all" },
{ "record": "DKIM", "name": "ts2610._domainkey.acme.com", "type": "TXT", "ttl": "Auto", "status": "verified",
"value": "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA…" },
{ "record": "DMARC", "name": "_dmarc.acme.com", "type": "TXT", "ttl": "Auto", "status": "pending",
"value": "v=DMARC1; p=none; rua=mailto:reports@system.tsmart.ai; fo=1" },
{ "record": "MX", "name": "acme.com", "type": "MX", "ttl": "Auto", "status": "pending",
"value": "mail.tsmart.ai.", "priority": 10 }
]
} status | Meaning |
|---|---|
not_started | Ownership is not proven yet. |
pending | Ownership is proven, but neither SPF nor DKIM was found in place. |
partially_verified | One of SPF and DKIM is in place, the other is missing or wrong. |
verified | SPF and DKIM are in place. The domain can send. |
capabilities.sending becomes enabled as soon as ownership is proven; only
status: "verified" means the domain can actually send. capabilities.receiving shows whether
the domain's incoming mail is handled by tsmart.ai.
What blocks sending
| Situation | Answer to POST /emails |
|---|---|
The domain of from is not a domain of your company, or its ownership is not proven | 403 invalid_from_address |
| The key is a sending-access key restricted to a different domain | 403 invalid_from_address |
| SPF or DKIM was not in place at the latest check | 403 domain_not_verified |
The platform also re-checks the records of every verified domain regularly. If SPF or DKIM disappears, sending from
the domain stops with domain_not_verified until the record is back and checked again. A record that
passed before and fails is re-checked once after a short pause, so a single slow name server does not stop sending.
A scheduled email whose domain is no longer ready when it comes due fails with an email.failed event.
Tracking and removal
Open and click tracking are switched per domain with PATCH /domains/{id}
(open_tracking, click_tracking), both off by default; see
Sending email. A domain is removed in the console or with
DELETE /domains/{id}, which needs a key created by a company owner and is refused with
409 resource_in_use while the domain still has mailboxes.
Webhooks can subscribe to domain.created, domain.updated and domain.deleted;
see Webhooks.