Quick Start
Use this sample from your backend server. Never call the reseller API directly from public JavaScript or a mobile app bundle.
curl -X POST "https://reseller.co.tz/api/v1/domains/check" \
-H "X-API-KEY: your_reseller_api_key" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"domain_name": "example.co.tz"}'
Authentication
Every request must include the reseller API key shown inside the reseller portal API Access page.
| Header | X-API-KEY: your_reseller_api_key |
|---|---|
| Account scope | Only active reseller accounts can authenticate. Admin users and suspended resellers are rejected. |
| IP whitelist | The caller IP must be listed on the reseller API Access page. If no IPs are configured, API access is blocked. |
| Domain scope | All domain endpoints are restricted to domains owned by the authenticated reseller. |
Response Format
Success
{
"success": true,
"message": "Domain synced successfully.",
"data": {
"domain": {
"id": 123,
"domain_name": "example.co.tz",
"status": "active"
}
}
}
Failure
{
"success": false,
"message": "The request could not be validated.",
"errors": {
"domain_name": [
"The domain name field is required."
]
}
}
Billing Safety
Registration, renewal, and transfer are billable when a price is configured. Free actions include sync, fetch nameservers, fetch Whois, fetch EPP, lock status, and privacy status.
- Balance is checked before the provider call.
- The reseller row is locked before funds are deducted.
- Funds are deducted only after the provider returns success.
- The domain update and ledger transaction are saved inside one database transaction.
- A reconciliation audit event is written after successful registration or renewal billing.
- If the provider succeeds but local billing fails, a failed billing audit event is written for admin review.
Endpoints
| Method | Endpoint | Description |
|---|---|---|
| GET | /domains |
List the authenticated reseller's domains. |
| GET | /domains/{domain} |
Get one owned domain by portal ID or domain name. |
| POST | /domains/check |
Check availability and return matching active catalog pricing. |
| POST | /domains/register |
Register a domain and charge reseller balance after provider success. |
| POST | /domains/{domain}/renew |
Renew an owned domain and charge reseller balance after provider success. |
| POST | /domains/{domain}/transfer |
Submit transfer for an owned domain and charge configured transfer price after provider success. |
| POST | /domains/{domain}/sync |
Refresh local expiry, status, lock, privacy, and safe registry metadata from the provider. |
| GET | /domains/{domain}/nameservers |
Fetch current nameservers from the provider. |
| POST | /domains/{domain}/nameservers |
Update nameservers. Send 2 to 6 valid hostnames. |
| GET | /domains/{domain}/whois |
Fetch current Whois contact details from the provider. |
| POST | /domains/{domain}/whois |
Update registrant and admin Whois contacts. |
| POST | /domains/{domain}/epp-code |
Request the current EPP code from the provider. |
| PUT | /domains/{domain}/epp-code |
Set a new EPP code when supported by the provider. |
| GET | /domains/{domain}/lock |
Fetch domain lock status when the provider supports lock management. |
| PUT | /domains/{domain}/lock |
Enable or disable domain lock. Send locked true or false. |
| GET | /domains/{domain}/privacy |
Fetch Whois privacy status when the provider supports privacy protection. |
| PUT | /domains/{domain}/privacy |
Enable or disable privacy protection. Send enabled true or false. |
| GET | /domains/{domain}/dns |
Fetch DNS management status and editable records for an owned domain. |
| POST | /domains/{domain}/dns/provision |
Enable DNS management for an owned domain when the addon is available. |
| DELETE | /domains/{domain}/dns |
Cancel DNS management for an owned domain. |
| POST | /domains/{domain}/dns/records |
Create a DNS record. Supported types: A, AAAA, CNAME, MX, TXT, SRV, CAA, and NS. |
| PUT | /domains/{domain}/dns/records/{record} |
Update a DNS record by record line or record ID. |
| DELETE | /domains/{domain}/dns/records/{record} |
Delete a DNS record by record line or record ID. |
DNS Management
DNS endpoints are scoped to domains owned by the authenticated reseller. DNS management must be active before records can be listed, created, updated, or deleted. Responses use generic DNS messages and do not expose internal infrastructure details.
| Domain identifier | Use either the portal domain ID or the full domain name in {domain}. |
|---|---|
| Record identifier | Use the record line value returned by GET /domains/{domain}/dns. If a record ID is returned by your integration, it can also be used where supported. |
| Supported record types | A, AAAA, CNAME, MX, TXT, SRV, CAA, and NS. |
| TTL range | ttl is optional and defaults to 14400. Valid range: 60 to 86400 seconds. |
| Name format | Use @ for the zone root, * for wildcard, or a hostname label such as www, mail, or _sip._tcp. |
A requires IPv4, AAAA requires IPv6, and hostname-based records such as CNAME, MX, SRV, and NS require valid hostnames.
Payload Examples
POST /domains/register
{
"domain_name": "example.co.tz",
"period": 1,
"nameservers": ["ns1.yatosha.com", "ns2.yatosha.com"],
"registrant": {
"name": "Domain Owner",
"organization": "Owner Company",
"address1": "123 Registry Road",
"city": "Dar es Salaam",
"state": "Dar es Salaam",
"postcode": "11101",
"country": "TZ",
"phone": "+255.754123456",
"email": "owner@example.co.tz"
},
"admin": {
"name": "Domain Admin",
"organization": "Owner Company",
"address1": "123 Registry Road",
"city": "Dar es Salaam",
"state": "Dar es Salaam",
"postcode": "11101",
"country": "TZ",
"phone": "+255.754123456",
"email": "admin@example.co.tz"
}
}
POST /domains/{domain}/renew
{
"period": 1
}
POST /domains/{domain}/nameservers
{
"nameservers": ["ns1.yatosha.com", "ns2.yatosha.com"]
}
POST /domains/{domain}/whois
{
"registrant": {
"name": "Domain Owner",
"organization": "Owner Company",
"address1": "123 Registry Road",
"city": "Dar es Salaam",
"state": "Dar es Salaam",
"postcode": "11101",
"country": "TZ",
"phone": "+255.754123456",
"email": "owner@example.co.tz"
},
"admin": {
"name": "Domain Admin",
"organization": "Owner Company",
"address1": "123 Registry Road",
"city": "Dar es Salaam",
"state": "Dar es Salaam",
"postcode": "11101",
"country": "TZ",
"phone": "+255.754123456",
"email": "admin@example.co.tz"
}
}
PUT /domains/{domain}/lock
{
"locked": true
}
PUT /domains/{domain}/privacy
{
"enabled": true
}
POST /domains/{domain}/dns/provision
{
"confirm": true
}
POST /domains/{domain}/dns/records
{
"type": "A",
"name": "www",
"value": "203.0.113.10",
"ttl": 14400
}
POST /domains/{domain}/dns/records
{
"type": "MX",
"name": "@",
"value": "mail.example.co.tz.",
"priority": 10,
"ttl": 14400
}
PUT /domains/{domain}/dns/records/{record}
{
"type": "TXT",
"name": "@",
"value": "v=spf1 include:example.net ~all",
"ttl": 3600
}
DELETE /domains/{domain}/dns/records/{record}
{
"note": "No request body is required. Replace {record} with the record line or ID returned by the DNS list endpoint."
}
Legacy API Compatibility
Use this only for existing integrations from the old reseller portal. The preferred API for new builds is /api/v1.
| Endpoint | POST https://reseller.co.tz/api/index.php |
|---|---|
| API key | Send X-API-KEY, body field api_key, or query field api_key. Header authentication is safest. |
| Response | Legacy responses use status, message, data, and meta.balance_before/balance_after. |
Supported Actions
| Action | Purpose |
|---|---|
checkDomain |
Check domain availability and catalog pricing. |
getDomainInfo |
Fetch provider domain information and sync local data when the domain is owned by the reseller. |
registerDomain |
Register a domain and deduct reseller funds only after provider success. |
getNameservers |
Fetch current nameservers for an owned domain. |
updateNameservers |
Update nameservers for an owned domain. |
getContactDetails / getWhois |
Fetch Whois contact details for an owned domain. |
updateContactDetails / updateWhois |
Update Whois contacts for an owned domain. |
renewDomain |
Renew an owned domain and deduct reseller funds only after provider success. |
getEPPCode |
Request the current EPP code for an owned domain. |
transferDomain |
Submit a transfer request with authCode and charge the configured transfer price after provider success. |
getBalance |
Return the reseller balance. |
Check domain
curl -X POST "https://reseller.co.tz/api/index.php" \
-H "X-API-KEY: your_reseller_api_key" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"action": "checkDomain",
"domainName": "example.co.tz"
}'
Renew domain
curl -X POST "https://reseller.co.tz/api/index.php" \
-H "X-API-KEY: your_reseller_api_key" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"action": "renewDomain",
"domainName": "example.co.tz",
"period": 1
}'
Register domain with old field names
{
"action": "registerDomain",
"domainName": "example.co.tz",
"period": 1,
"nameservers": ["ns1.yatosha.com", "ns2.yatosha.com"],
"registrantInfo": {
"name": "Domain Owner",
"organization": "Owner Company",
"address": "123 Registry Road",
"city": "Dar es Salaam",
"state": "Dar es Salaam",
"postalCode": "11101",
"country": "TZ",
"phone": "+255.754123456",
"email": "owner@example.co.tz"
},
"adminInfo": {
"name": "Domain Admin",
"organization": "Owner Company",
"address": "123 Registry Road",
"city": "Dar es Salaam",
"state": "Dar es Salaam",
"postalCode": "11101",
"country": "TZ",
"phone": "+255.754123456",
"email": "admin@example.co.tz"
}
}
Status Codes
| 200 | Request completed successfully. |
|---|---|
| 201 | Domain registration completed and local billing was recorded. |
| 401 | Missing or invalid API key. |
| 403 | API key is valid, but the caller IP is not whitelisted for that reseller account. |
| 404 | Domain not found in the authenticated reseller account. |
| 422 | Validation failed, provider rejected the request, unsupported provider capability, or insufficient balance. |
| 429 | Too many requests. |
| 500 | Unexpected server error. The API log will capture the failed request for review. |
Logging And Reconciliation
Every request is captured in the API Logs page, including invalid keys and failed validation. Sensitive fields such as API keys, EPP codes, auth codes, passwords, tokens, and secrets are removed before logs are saved.
Security Notes
- Use HTTPS for every request.
- Add only your server-side integration IP addresses to the API whitelist.
- Store API keys in backend environment variables or a secret manager.
- Never expose API keys in frontend code, mobile app bundles, logs, screenshots, or public repositories.
- Regenerate the API key from the reseller portal if a key may have been exposed.
- Use idempotency on your side for retry logic around billable actions.