Your Domain Reseller Plan lets you register and manage .tz domains from your own WHMCS (or from your own software) at wholesale prices. Registrations and renewals are charged to your reseller wallet; transfers are free. This page covers everything you need: where to find your credentials, how to install the WHMCS module, and the full API reference.

1. Where to find what you need

  • Your credentials (API Key and API Secret): log in at billing.sakurahost.co.tz, open Services → Domain Reseller Plan. The page also shows your wallet balance, your wholesale prices and your domains.
  • WHMCS module: sakurareseller-1.0.0.zip
  • Top up your balance, any amount, any time: log in and use Add Funds. It is available as soon as the payment is confirmed. Your balance is your account credit; the module and the API charge it, and your service page shows the same figure.

2. Install the WHMCS module

  1. Download the zip and unzip it. Upload the modules folder into the root of your WHMCS (it adds modules/registrars/sakurareseller/).
  2. In your WHMCS admin go to Configuration → System Settings → Domain Registrars, find Sakura .TZ Domain Reseller and click Activate.
  3. Enter your API Key and API Secret. Leave the endpoint as it is. Save.
  4. Go to Configuration → System Settings → Domain Pricing. Add the extensions you sell (.co.tz, .or.tz, .ac.tz, .tz and every other .tz extension in your price list), set Auto Registration to Sakura .TZ Domain Reseller and set your own selling prices. Your wholesale prices are on your service page.
  5. Place a test order for a domain you want. WHMCS registers it through the module and your wallet is charged automatically.

The module supports registration, renewal, transfer in, nameservers, registrar lock, EPP/auth code, contact details, expiry sync and availability search. Deleting a domain is not offered; contact support if you need one removed.

3. API reference

Use the API directly if you are not using WHMCS.

URL: https://billing.sakurahost.co.tz/modules/addons/sakura_reseller/api.php?endpoint=ENDPOINT
Method: POST with a JSON body (send {} when there are no fields).

Authentication

Every request carries three headers:

HeaderValue
AuthorizationBearer YOUR_API_KEY
X-TimestampCurrent Unix time in seconds (must be within 5 minutes of our clock)
X-SignatureLower-case hex of HMAC-SHA256(API_SECRET, TIMESTAMP + ":" + RAW_BODY)

Sign the exact bytes you send as the body. Keep the API Secret on your server only; never put it in browser code or a mobile app.

# shell
BODY='{"domains":["example.co.tz"]}'
TS=$(date +%s)
SIG=$(printf '%s' "$TS:$BODY" | openssl dgst -sha256 -hmac "$API_SECRET" -hex | awk '{print $NF}')
curl -X POST "https://billing.sakurahost.co.tz/modules/addons/sakura_reseller/api.php?endpoint=domain/check" \
  -H "Authorization: Bearer $API_KEY" -H "X-Timestamp: $TS" -H "X-Signature: $SIG" \
  -H "Content-Type: application/json" -d "$BODY"
// PHP
$body = json_encode(['domains' => ['example.co.tz']]);
$ts   = time();
$sig  = hash_hmac('sha256', $ts . ':' . $body, $apiSecret);
$ch = curl_init('https://billing.sakurahost.co.tz/modules/addons/sakura_reseller/api.php?endpoint=domain/check');
curl_setopt_array($ch, [CURLOPT_POST => true, CURLOPT_POSTFIELDS => $body, CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => ['Content-Type: application/json', "Authorization: Bearer $apiKey", "X-Timestamp: $ts", "X-Signature: $sig"]]);
$result = json_decode(curl_exec($ch), true);

Responses

Success: {"status":"success","data":{...}}
Error: {"status":"error","message":"..."}

HTTPMeaning
200Done
400 / 422Request or field problem; the message says which field
401Authentication failed (key, signature or timestamp)
402Wallet balance too low for this action
403Not allowed: suspended account, domain limit reached, address not on your allow-list, or the domain is not in your account
404 / 409Unknown endpoint / the domain already exists
429Too many requests, or too many failed logins (wait 10 minutes)
502 / 503The .tz registry returned an error or is unavailable. You are not charged when this happens

Endpoints

EndpointBody fieldsReturns
account/balancenonebalance, currency, tier, domain_limit, domains_used
pricing/tldsnoneyour register / renew / transfer price per extension
domain/checkdomains: array of up to 20 namesresults: name → available / registered / unknown
domain/suggestquery, optional limitsuggested names to check
domain/registerdomain, years (1-10), nameservers (2 to 10), registrant objectregistered, expiry, charged
domain/renewdomain, yearsrenewed, new expiry, charged
domain/transferdomain, auth_codetransfer_initiated, charged (always 0). Transfers are free and keep the domain's current expiry date
domain/infodomainstatus, locked, expiry, created, transfer_pending
domain/listnoneevery domain in your account with status and expiry
domain/nameserversdomain; add nameservers (array) to change themcurrent nameservers, or updated
domain/lockdomain, locked (true / false)locked
domain/contactsdomain; add registrant to change itregistrant details, or updated
domain/eppcodedomaina new transfer (auth) code

The registrant object

{
  "firstname": "Amina", "lastname": "Juma", "companyname": "Optional Ltd",
  "email": "amina@example.com", "phonenumber": "+255.712345678",
  "address1": "Samora Avenue 12", "address2": "", "city": "Dar es Salaam",
  "state": "Dar es Salaam", "postcode": "11101", "country": "TZ"
}

Required: firstname, lastname, email, phonenumber, address1, city. Phone numbers are written like +255.712345678; a Tanzanian number such as 0712345678 is also accepted.

Example: register a domain

POST ...api.php?endpoint=domain/register
{"domain":"example.co.tz","years":1,
 "nameservers":["ns1.yourdns.co.tz","ns2.yourdns.co.tz"],
 "registrant":{ ...as above... }}

200 {"status":"success","data":{"domain":"example.co.tz","registered":true,
     "expiry":"2027-10-26","charged":25000,"currency":"TZS"}}

4. How charging works

  • Registration and renewal are charged from your wallet at your tier's price multiplied by the number of years, before the registry is asked. Transfers in are free.
  • If the registry refuses the request, the charge is returned to your wallet straight away and recorded in your transactions. Invalid requests and name-already-taken replies are never charged.
  • If your balance is too low you receive HTTP 402 and nothing is registered. Add Funds, then try again.
  • If an extension is temporarily unavailable at the registry you receive HTTP 503 and are not charged. Try again later or contact support.

5. Limits and security

  • Up to 120 requests a minute per IP address. Fifteen failed logins from one address block it for 10 minutes.
  • You can only read or change domains that are in your own reseller account.
  • For extra safety we can restrict your account to your server's IP addresses. Ask support and send the addresses.
  • If your API Secret may have leaked, contact support immediately and we will issue new credentials.

6. Test with the sandbox

Build and test your integration without spending money. Your service page shows a separate Test API Key and Test API Secret (the key starts with test_). Use them exactly like the live ones: same endpoint, same headers, same signing. The only difference is that nothing real happens.

  • No registry is contacted, nothing is charged, no email is sent and nothing is saved. Every answer carries "sandbox": true next to "status".
  • Names starting with taken (for example takenshop.co.tz) show as already registered; names starting with lowfunds return the “balance too low” error (402); names starting with unknown return “unknown” at check. Any other valid name behaves as available and registers successfully.
  • domain/list returns two sample domains and account/balance shows a fixed test balance of TZS 1,000,000.
  • Input is checked like the live API, so missing contact fields, bad name servers and unsupported extensions return the same errors.

When your tests pass, switch to your live key and secret.

7. Support

Email hello@sakuragroup.co.tz or WhatsApp +255 758 309 999. Please include the domain name and the exact message you received.

8. What is new

  • 27 October 2026: sandbox test keys; health check at ?endpoint=ping; the reseller portal now shows your API domains, an API Activity page and an Integrations page with downloads.
  • 26 October 2026: every request is signed (X-Timestamp and X-Signature) and can be limited to your server IPs; one balance for the wallet and your billing account; transfers are free; a failed registration is refunded automatically; emails are sent only when something needs your action.
Was this answer helpful? 0 Users Found This Useful (0 Votes)