Documentation
Guides and the API
All guides
22 guides
Point your domain at your site 3 min read What .com.ng needs from you 2 min read Add a DNS record by hand 3 min read Use a domain from another registrar 3 min read Deploy your first repo 4 min read Which frameworks are detected 2 min read Deploy with a Dockerfile 5 min read Read a failed build log 4 min read Set environment variables 2 min read Create a mailbox 1 min read Set up mail on your phone 3 min read Set up Outlook or Apple Mail 3 min read Why mail lands in spam 4 min read View your invoices 1 min read What happens when a payment fails 2 min read Connect to your database 3 min read Upload project files 3 min read Schedule a cron job 2 min read Turn on two-factor sign-in 2 min read Invite a team member 2 min read Create an API key 2 min read Recover a locked account 3 min read
API reference
Scoped keys · REST · examples use placeholder data
Authentication
Create a key in Dashboard → API keys. Keys look like tsc_…, are shown exactly once, and carry only the
scopes you pick. Send the key as a bearer token:
curl https://tsoftcloud.com/api/v1/services \
-H "Authorization: Bearer tsc_your_key_here" 401 means a missing or revoked key; 403 names the scope the key
lacks.
Conventions
- Money is always integer minor units as strings (
"800000"= ₦8,000.00) with an explicit ISO currency — never floats. - Timestamps are ISO 8601 in UTC.
- Responses wrap payloads in
{ "data": … }; errors in{ "error": "…" }. - Rate limit: 120 requests/minute per key — exceeding it returns
429with aRetry-Afterheader. - Registrar-backed reads degrade honestly:
"available": falseplus a message, never a 500.
GET /api/v1/services
{
"data": [
{
"id": 12,
"type": "email",
"name": "Business email — verifytest.ng",
"domain": "verifytest.ng",
"status": "active",
"cycle": "annually",
"amount_minor": "1500000",
"currency": "NGN",
"next_due_date": null,
"created_at": "2026-07-03T04:05:00.000Z"
}
]
}GET /api/v1/invoices
{
"data": [
{
"id": 34,
"number": "INV-2026-0034",
"status": "paid",
"currency": "NGN",
"subtotal_minor": "800000",
"tax_minor": "0",
"total_minor": "800000",
"due_date": "2026-08-01T00:00:00.000Z",
"paid_at": "2026-07-20T09:12:00.000Z",
"created_at": "2026-07-18T10:00:00.000Z"
}
]
}GET /api/v1/domains
{
"data": [
{
"id": 8,
"domain": "yourbrand.com.ng",
"status": "active",
"next_due_date": "2027-07-01T00:00:00.000Z",
"created_at": "2026-07-01T09:00:00.000Z"
}
]
}GET /api/v1/domains/{domain}
{
"data": {
"domain": "yourbrand.com.ng",
"available": true,
"registrar_status": "active",
"expires_at": "2027-07-01T00:00:00.000Z",
"locked": true,
"whois_privacy": true,
"nameservers": ["dns1.example.net", "dns2.example.net"]
}
}
// When the registrar can't answer, "available": false arrives with a
// human-readable "message" instead of an error — degradation is honest.GET · PUT /api/v1/domains/{domain}/dns
// PUT replaces the ENTIRE zone — read, modify, then write back.
curl -X PUT https://tsoftcloud.com/api/v1/domains/yourbrand.com.ng/dns \
-H "Authorization: Bearer tsc_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"records": [
{ "type": "A", "name": "@", "address": "203.0.113.10", "ttl": 1800 },
{ "type": "MX", "name": "@", "address": "mail.yourbrand.com.ng", "mxPriority": 10 }
]
}'
// → { "data": { "domain": "yourbrand.com.ng", "records": 2, "applied": true } }GET · PUT /api/v1/domains/{domain}/nameservers
// PUT body: 2–5 hostnames. Custom nameservers override the DNS zone above.
{ "nameservers": ["ns1.yourdns.com", "ns2.yourdns.com"] }
// → { "data": { "domain": "…", "nameservers": [...], "applied": true } }Need a higher limit?
The domains:read and dns:write scopes are live. Want a higher
rate limit, or an endpoint we don't have yet?