Quick Start
Integrate our API into your backend in seconds using standard HTTP tools like cURL.
curl -X POST "https://reseller.co.tz/api/v1/domains/check" \
-H "X-API-KEY: your_reseller_api_key" \
-H "Accept: application/json" \
-d '{"domain_name": "example.co.tz"}'
Integration guide
Complete, step-by-step guides for resellers and their technical partners. Both include request
and response examples for cURL, PHP/Laravel, Node.js and plain PHP, plus workflow, testing and
troubleshooting checklists. The Domains guide covers domain management only (DNS record management is
not included); the SMS guide covers sending, logs and delivery reports.
Domains API integration guide and examples
PDF · Version 1.0 · 556 KB
SMS API integration guide and examples
PDF · Version 1.0 · 474 KB
Share these guides with your developers or system integrators. They contain public API instructions only and no account credentials.
Authentication
Domain API requests use your reseller API key. SMS API requests use the separate SMS bearer token shown on the SMS Reseller dashboard.
Header
Value
X-API-KEY
Your unique reseller API key for domain API endpoints
Authorization
Bearer your_sms_bearer_token for SMS sending, logs, and delivery reports
Accept
application/json
The SMS bearer token is separate from the domain API key. You can regenerate or disable it from the SMS Reseller dashboard without affecting domain API access.
Response Formats
Every v1 response uses a predictable JSON envelope. Registry and DNS errors are intentionally general so provider details, private configuration, and credentials stay hidden from public integrations.
Success
{
"success": true,
"message": "Domain renewed successfully.",
"data": {
"domain": {
"domain_name": "example.co.tz",
"status": "active"
}
}
}
Validation or Registry Error
{
"success": false,
"message": "The registry could not complete this request. Please try again later.",
"errors": {
"registry": [
"The registry could not complete this request. Please try again later."
]
}
}
Domain actions and endpoints
Every domain action on the reseller API. Search for an endpoint, open it for parameters and
examples, then copy the cURL command. Replace {domain} with a portal domain ID
or the full domain name, and {record} with a record line or record ID.
https://reseller.co.tz/api/v1
Search endpoints
29 endpoints
Find and inspect domains
GET
/domains
List the domains owned by your reseller account with search, status filter and pagination.
GET
/domains/{domain}
Read one owned domain, including expiry, lock, privacy and the exact renewal price.
POST
/domains/check
Check availability and return catalog pricing plus the reserved, premium and bookable flags.
Register, re-register and renew
POST
/domains/register
Register a new domain, create the portal ownership record, and charge the reseller balance after registry success.
POST
/domains/{domain}/register
Register an owned cancelled domain again, reusing the existing portal domain record.
POST
/domains/{domain}/renew
Renew an owned domain for one or more years and charge the reseller balance after registry success.
POST
/domains/{domain}/sync
Refresh local status, expiry, lock, privacy and safe registry metadata from the registry.
Transfer a domain in
POST
/domains/{domain}/transfer
Submit a domain transfer with the Auth/EPP code and charge the transfer price after registry success.
Nameservers and glue records
Transfer lock, privacy and EPP codes
SMS sending and logs
POST
/sms/send
Send one SMS from the reseller SMS wallet and record the gateway attempt.
GET
/sms/logs
List your own SMS attempts with status, source, recipient, sender ID and cost.
GET
/sms/delivery-reports
Read delivery reports for your own SMS attempts, including submit-level delivery status.
No endpoint matches that search.
Find and inspect domains
Search availability, list the domains you own, and read a single domain record.
Query parameters
q
optional search text matched against the domain name
status
optional one of active, expired, pending, pending_transfer, cancelled
per_page
optional integer 1-100, default 25
page
optional integer page number
Good to know
Only domains owned by the API key account are returned.
Send status=all (or omit status) to search every status.
cURL
curl -X GET "https://reseller.co.tz/api/v1/domains" \
-H "X-API-KEY: $RESELLER_API_KEY" \
-H "Accept: application/json"
Sample response (200 OK)
{
"success": true,
"message": "Domains loaded successfully.",
"data": {
"domains": [
{
"id": 123,
"domain_name": "example.co.tz",
"status": "active",
"registry_status": "active",
"redemption_state": "grace",
"in_redemption": false,
"renewal_price": 20000,
"redemption_price": null,
"registration_date": "2026-05-28",
"expiry_date": "2027-05-28",
"lock_status": false,
"privacy_status": false,
"last_synced_at": "2026-05-28T12:00:00.000000Z"
}
],
"pagination": {
"current_page": 1,
"per_page": 25,
"total": 1,
"last_page": 1
}
}
}
Path parameters
domain
required portal domain ID or full domain name
Good to know
in_redemption is true when the registry has already moved the domain into its restoration window.
When in_redemption is true, show redemption_price for the first year; extra years use renewal_price.
cURL
curl -X GET "https://reseller.co.tz/api/v1/domains/{domain}" \
-H "X-API-KEY: $RESELLER_API_KEY" \
-H "Accept: application/json"
Sample response (200 OK)
{
"success": true,
"message": "Domain loaded successfully.",
"data": {
"domain": {
"id": 123,
"domain_name": "example.co.tz",
"status": "active",
"registry_status": "active",
"redemption_state": "grace",
"in_redemption": false,
"renewal_price": 20000,
"redemption_price": null,
"registration_date": "2026-05-28",
"expiry_date": "2027-05-28",
"lock_status": false,
"privacy_status": false,
"last_synced_at": "2026-05-28T12:00:00.000000Z"
}
}
}
Body parameters
domain_name
required full domain name including the extension, max 253 characters
Good to know
available and bookable are usually the same. reserved means the registry blocks the name, premium means the registry prices it per name.
Always quote premium names from price.registration before charging a customer.
A domain already managed in this portal is reported as unavailable.
cURL
curl -X POST "https://reseller.co.tz/api/v1/domains/check" \
-H "X-API-KEY: $RESELLER_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"domain_name":"example.co.tz"}'
Request body
{
"domain_name": "example.co.tz"
}
Sample response (200 OK)
{
"success": true,
"message": "Domain availability checked successfully.",
"data": {
"domain_name": "example.co.tz",
"available": true,
"bookable": true,
"reserved": false,
"premium": false,
"price": {
"registration": 20000,
"renewal": 20000,
"transfer": 0,
"premium_registration": null,
"premium_sellable": false
}
}
}
Register, re-register and renew
Billable actions that create ownership or extend an expiry date. Your balance is charged only after the registry accepts the order.
Body parameters
domain_name
required full domain name that is not already in the portal
period
required integer 1-10 years
nameservers
required array of 2-10 hostnames
registrant
required contact object, see schemas.contact
admin
required contact object, see schemas.contact
same_contact
optional boolean. true copies the registrant onto the admin contact, so admin can be omitted
provision_dns
optional boolean. true enables DNS management after successful registration
Good to know
The wallet balance is checked before the registry call and charged only after the registry confirms success.
Some extensions have registry rules. For example .co.za requires the registrant country to be South Africa (ZA).
Reserved and premium names are rejected unless the extension has a sellable premium price configured.
Treat this endpoint as non-idempotent and add your own retry guard.
cURL
curl -X POST "https://reseller.co.tz/api/v1/domains/register" \
-H "X-API-KEY: $RESELLER_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"domain_name":"example.co.tz","period":1,"nameservers":["ns1.example.co.tz","ns2.example.co.tz"],"same_contact":true,"registrant":{"name":"Jane Doe","organization":"Jane Doe Ltd","address1":"123 Registry Road","city":"Dar es Salaam","state":"Dar es Salaam","postcode":"11101","country":"TZ","phone":"+255.754123456","email":"jane@example.co.tz"},"admin":{"name":"Jane Doe","organization":"Jane Doe Ltd","address1":"123 Registry Road","city":"Dar es Salaam","state":"Dar es Salaam","postcode":"11101","country":"TZ","phone":"+255.754123456","email":"jane@example.co.tz"}}'
Request body
{
"domain_name": "example.co.tz",
"period": 1,
"nameservers": [
"ns1.example.co.tz",
"ns2.example.co.tz"
],
"same_contact": true,
"registrant": {
"name": "Jane Doe",
"organization": "Jane Doe Ltd",
"address1": "123 Registry Road",
"city": "Dar es Salaam",
"state": "Dar es Salaam",
"postcode": "11101",
"country": "TZ",
"phone": "+255.754123456",
"email": "jane@example.co.tz"
},
"admin": {
"name": "Jane Doe",
"organization": "Jane Doe Ltd",
"address1": "123 Registry Road",
"city": "Dar es Salaam",
"state": "Dar es Salaam",
"postcode": "11101",
"country": "TZ",
"phone": "+255.754123456",
"email": "jane@example.co.tz"
}
}
Sample response (201 Created)
{
"success": true,
"message": "Domain registered successfully.",
"data": {
"domain": {
"id": 123,
"domain_name": "example.co.tz",
"status": "active",
"registry_status": "active",
"redemption_state": "grace",
"in_redemption": false,
"renewal_price": 20000,
"redemption_price": null,
"registration_date": "2026-05-28",
"expiry_date": "2027-05-28",
"lock_status": false,
"privacy_status": false,
"last_synced_at": "2026-05-28T12:00:00.000000Z"
},
"dns": null,
"amount_charged": 20000
}
}
Path parameters
domain
required portal domain ID or full domain name with cancelled status
Body parameters
period
required integer 1-10 years
nameservers
required array of 2-10 hostnames
registrant
required contact object, see schemas.contact
admin
required contact object, see schemas.contact
same_contact
optional boolean, true to reuse the registrant details
provision_dns
optional boolean
Good to know
Only a domain the account already owns with status cancelled can be re-registered.
A cancelled domain is registered at the normal registration price, not the restoration price.
cURL
curl -X POST "https://reseller.co.tz/api/v1/domains/{domain}/register" \
-H "X-API-KEY: $RESELLER_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"period":1,"nameservers":["ns1.example.co.tz","ns2.example.co.tz"],"same_contact":true,"registrant":{"name":"Jane Doe","organization":"Jane Doe Ltd","address1":"123 Registry Road","city":"Dar es Salaam","state":"Dar es Salaam","postcode":"11101","country":"TZ","phone":"+255.754123456","email":"jane@example.co.tz"},"admin":{"name":"Jane Doe","organization":"Jane Doe Ltd","address1":"123 Registry Road","city":"Dar es Salaam","state":"Dar es Salaam","postcode":"11101","country":"TZ","phone":"+255.754123456","email":"jane@example.co.tz"}}'
Request body
{
"period": 1,
"nameservers": [
"ns1.example.co.tz",
"ns2.example.co.tz"
],
"same_contact": true,
"registrant": {
"name": "Jane Doe",
"organization": "Jane Doe Ltd",
"address1": "123 Registry Road",
"city": "Dar es Salaam",
"state": "Dar es Salaam",
"postcode": "11101",
"country": "TZ",
"phone": "+255.754123456",
"email": "jane@example.co.tz"
},
"admin": {
"name": "Jane Doe",
"organization": "Jane Doe Ltd",
"address1": "123 Registry Road",
"city": "Dar es Salaam",
"state": "Dar es Salaam",
"postcode": "11101",
"country": "TZ",
"phone": "+255.754123456",
"email": "jane@example.co.tz"
}
}
Sample response (201 Created)
{
"success": true,
"message": "Domain registered successfully.",
"data": {
"domain": {
"id": 123,
"domain_name": "example.co.tz",
"status": "active",
"registry_status": "active",
"redemption_state": "grace",
"in_redemption": false,
"renewal_price": 20000,
"redemption_price": null,
"registration_date": "2026-05-28",
"expiry_date": "2027-05-28",
"lock_status": false,
"privacy_status": false,
"last_synced_at": "2026-05-28T12:00:00.000000Z"
},
"dns": null,
"amount_charged": 20000
}
}
Path parameters
domain
required portal domain ID or full domain name
Body parameters
period
required integer 1-10 years
Good to know
Domains in the registry restoration window cost redemption_price for the first year; extra years use renewal_price.
Read the domain first (GET /domains/{domain}) to show the same amount this endpoint will charge.
If the registry cannot be reached, the API returns a retry message and no charge is made.
cURL
curl -X POST "https://reseller.co.tz/api/v1/domains/{domain}/renew" \
-H "X-API-KEY: $RESELLER_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"period":1}'
Request body
Sample response (200 OK)
{
"success": true,
"message": "Domain renewed successfully.",
"data": {
"domain": {
"id": 123,
"domain_name": "example.co.tz",
"status": "active",
"registry_status": "active",
"redemption_state": "grace",
"in_redemption": false,
"renewal_price": 20000,
"redemption_price": null,
"registration_date": "2026-05-28",
"expiry_date": "2028-05-28",
"lock_status": false,
"privacy_status": false,
"last_synced_at": "2026-05-28T12:00:00.000000Z"
}
}
}
Path parameters
domain
required portal domain ID or full domain name
Good to know
Never billable. Use it after a transfer completes or when a customer disputes the expiry date.
cURL
curl -X POST "https://reseller.co.tz/api/v1/domains/{domain}/sync" \
-H "X-API-KEY: $RESELLER_API_KEY" \
-H "Accept: application/json"
Sample response (200 OK)
{
"success": true,
"message": "Domain synced successfully.",
"data": {
"domain": {
"id": 123,
"domain_name": "example.co.tz",
"status": "active",
"registry_status": "active",
"redemption_state": "grace",
"in_redemption": false,
"renewal_price": 20000,
"redemption_price": null,
"registration_date": "2026-05-28",
"expiry_date": "2027-05-28",
"lock_status": false,
"privacy_status": false,
"last_synced_at": "2026-05-28T12:00:00.000000Z"
}
}
}
Transfer a domain in
Move an existing domain to this platform with its Auth/EPP code.
Path parameters
domain
required full domain name to transfer
Body parameters
auth_code
required string 6-128 characters. Never log or store it
registrant
optional contact object when the registry must match an existing contact
admin
optional contact object
Good to know
Auth codes are never echoed back in API responses or stored in the portal.
A transfer only completes when the current registrar releases the domain. Poll with POST /domains/{domain}/sync.
The domain shows status pending_transfer until the registry finishes the move.
cURL
curl -X POST "https://reseller.co.tz/api/v1/domains/{domain}/transfer" \
-H "X-API-KEY: $RESELLER_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"auth_code":"sample-transfer-code","registrant":{"name":"Jane Doe","organization":"Jane Doe Ltd","address1":"123 Registry Road","city":"Dar es Salaam","state":"Dar es Salaam","postcode":"11101","country":"TZ","phone":"+255.754123456","email":"jane@example.co.tz"},"admin":{"name":"Jane Doe","organization":"Jane Doe Ltd","address1":"123 Registry Road","city":"Dar es Salaam","state":"Dar es Salaam","postcode":"11101","country":"TZ","phone":"+255.754123456","email":"jane@example.co.tz"}}'
Request body
{
"auth_code": "sample-transfer-code",
"registrant": {
"name": "Jane Doe",
"organization": "Jane Doe Ltd",
"address1": "123 Registry Road",
"city": "Dar es Salaam",
"state": "Dar es Salaam",
"postcode": "11101",
"country": "TZ",
"phone": "+255.754123456",
"email": "jane@example.co.tz"
},
"admin": {
"name": "Jane Doe",
"organization": "Jane Doe Ltd",
"address1": "123 Registry Road",
"city": "Dar es Salaam",
"state": "Dar es Salaam",
"postcode": "11101",
"country": "TZ",
"phone": "+255.754123456",
"email": "jane@example.co.tz"
}
}
Sample response (200 OK)
{
"success": true,
"message": "Domain transfer submitted successfully.",
"data": {
"domain": {
"id": 123,
"domain_name": "example.co.tz",
"status": "pending_transfer",
"registry_status": "pending_transfer",
"redemption_state": "grace",
"in_redemption": false,
"renewal_price": 20000,
"redemption_price": null,
"registration_date": "2026-05-28",
"expiry_date": "2027-05-28",
"lock_status": false,
"privacy_status": false,
"last_synced_at": "2026-05-28T12:00:00.000000Z"
}
}
}
Nameservers and glue records
Point a domain at your DNS provider, including child nameservers with glue IP addresses.
Path parameters
domain
required portal domain ID or full domain name
cURL
curl -X GET "https://reseller.co.tz/api/v1/domains/{domain}/nameservers" \
-H "X-API-KEY: $RESELLER_API_KEY" \
-H "Accept: application/json"
Sample response (200 OK)
{
"success": true,
"message": "Nameservers loaded successfully.",
"data": {
"nameservers": [
"ns1.example.co.tz",
"ns2.example.co.tz"
]
}
}
Path parameters
domain
required portal domain ID or full domain name
Body parameters
nameservers
required array of 2-10 hostnames
provision_dns
optional boolean, keep true to use the portal DNS management addon
Good to know
Nameserver limits depend on the domain extension. The API rejects a list that is too long or too short.
cURL
curl -X POST "https://reseller.co.tz/api/v1/domains/{domain}/nameservers" \
-H "X-API-KEY: $RESELLER_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"nameservers":["ns1.example.co.tz","ns2.example.co.tz"]}'
Request body
{
"nameservers": [
"ns1.example.co.tz",
"ns2.example.co.tz"
]
}
Sample response (200 OK)
{
"success": true,
"message": "Nameservers updated successfully.",
"data": {
"nameservers": [
"ns1.example.co.tz",
"ns2.example.co.tz"
]
}
}
Path parameters
domain
required portal domain ID or full domain name
Query parameters
child_nsset_id
optional saved child nameserver set ID
cURL
curl -X GET "https://reseller.co.tz/api/v1/domains/{domain}/child-nameservers" \
-H "X-API-KEY: $RESELLER_API_KEY" \
-H "Accept: application/json"
Sample response (200 OK)
{
"success": true,
"message": "Child nameservers loaded successfully.",
"data": {
"child_nsset_id": "NSSET123",
"nameservers": [
{
"label": "ns1",
"name": "ns1.example.co.tz",
"addresses": [
"192.0.2.10"
]
},
{
"label": "ns2",
"name": "ns2.example.co.tz",
"addresses": [
"192.0.2.11"
]
}
]
}
}
Path parameters
domain
required portal domain ID or full domain name
Body parameters
child_nameserver_action
optional save_child_nameservers (default) or use_child_nameservers
child_nameservers
required array of 2-5 objects
child_nameservers[].label
required label such as ns1, or a full hostname inside the same domain
child_nameservers[].addresses
required comma or space separated IPv4/IPv6 glue addresses
Good to know
Use use_child_nameservers to save the set and switch the domain to it in one request.
cURL
curl -X POST "https://reseller.co.tz/api/v1/domains/{domain}/child-nameservers" \
-H "X-API-KEY: $RESELLER_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"child_nameserver_action":"use_child_nameservers","child_nameservers":[{"label":"ns1","addresses":"192.0.2.10, 2001:db8::10"},{"label":"ns2","addresses":"192.0.2.11"}]}'
Request body
{
"child_nameserver_action": "use_child_nameservers",
"child_nameservers": [
{
"label": "ns1",
"addresses": "192.0.2.10, 2001:db8::10"
},
{
"label": "ns2",
"addresses": "192.0.2.11"
}
]
}
Sample response (200 OK)
{
"success": true,
"message": "Child nameservers saved and applied successfully.",
"data": {
"child_nsset_id": "NSSET123",
"nameservers": [
{
"label": "ns1",
"name": "ns1.example.co.tz",
"addresses": [
"192.0.2.10",
"2001:db8::10"
]
},
{
"label": "ns2",
"name": "ns2.example.co.tz",
"addresses": [
"192.0.2.11"
]
}
]
}
}
DNS management
Create, update and delete DNS records for domains using the free DNS management addon.
Path parameters
domain
required portal domain ID or full domain name
Good to know
DNS management is a free addon that must be enabled per domain with POST /domains/{domain}/dns/provision.
cURL
curl -X GET "https://reseller.co.tz/api/v1/domains/{domain}/dns" \
-H "X-API-KEY: $RESELLER_API_KEY" \
-H "Accept: application/json"
Sample response (200 OK)
{
"success": true,
"message": "DNS records loaded successfully.",
"data": {
"dns_service": {
"id": 10,
"status": "active",
"zone": "example.co.tz"
},
"records": [
{
"line": 24,
"type": "A",
"name": "@",
"value": "192.0.2.10",
"ttl": 14400
},
{
"line": 25,
"type": "CNAME",
"name": "www",
"value": "example.co.tz",
"ttl": 14400
}
]
}
}
Path parameters
domain
required portal domain ID or full domain name
Good to know
The portal points the domain at the managed nameservers when the addon is enabled.
cURL
curl -X POST "https://reseller.co.tz/api/v1/domains/{domain}/dns/provision" \
-H "X-API-KEY: $RESELLER_API_KEY" \
-H "Accept: application/json"
Sample response (201 Created)
{
"success": true,
"message": "DNS management has been enabled.",
"data": {
"dns_service": {
"id": 10,
"status": "active",
"zone": "example.co.tz",
"provisioned_at": "2026-05-28T12:00:00.000000Z"
}
}
}
Path parameters
domain
required portal domain ID or full domain name
Good to know
Removing DNS management does not delete the domain, but the portal stops serving its zone.
cURL
curl -X DELETE "https://reseller.co.tz/api/v1/domains/{domain}/dns" \
-H "X-API-KEY: $RESELLER_API_KEY" \
-H "Accept: application/json"
Sample response (200 OK)
{
"success": true,
"message": "DNS management has been cancelled.",
"data": {
"dns_service": {
"id": 10,
"status": "cancelled",
"zone": "example.co.tz",
"cancelled_at": "2026-05-28T12:30:00.000000Z"
}
}
}
Path parameters
domain
required portal domain ID or full domain name
Body
required DNS record object, see schemas.dns_record
Good to know
Send replace_existing = true to overwrite an existing record with the same type and name instead of failing.
cURL
curl -X POST "https://reseller.co.tz/api/v1/domains/{domain}/dns/records" \
-H "X-API-KEY: $RESELLER_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"type":"A","name":"@","value":"192.0.2.10","ttl":14400,"replace_existing":true}'
Request body
{
"type": "A",
"name": "@",
"value": "192.0.2.10",
"ttl": 14400,
"replace_existing": true
}
Sample response (201 Created)
{
"success": true,
"message": "DNS record created successfully.",
"data": {
"records": [
{
"line": 24,
"type": "A",
"name": "@",
"value": "192.0.2.10",
"ttl": 14400
}
]
}
}
Path parameters
domain
required portal domain ID or full domain name
record
required record line or record ID returned by GET /domains/{domain}/dns
Body
required DNS record object, see schemas.dns_record
cURL
curl -X PUT "https://reseller.co.tz/api/v1/domains/{domain}/dns/records/{record}" \
-H "X-API-KEY: $RESELLER_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"type":"A","name":"@","value":"192.0.2.20","ttl":14400}'
Request body
{
"type": "A",
"name": "@",
"value": "192.0.2.20",
"ttl": 14400
}
Sample response (200 OK)
{
"success": true,
"message": "DNS record updated successfully.",
"data": {
"records": [
{
"line": 24,
"type": "A",
"name": "@",
"value": "192.0.2.20",
"ttl": 14400
}
]
}
}
Path parameters
domain
required portal domain ID or full domain name
record
required record line or record ID returned by GET /domains/{domain}/dns
cURL
curl -X DELETE "https://reseller.co.tz/api/v1/domains/{domain}/dns/records/{record}" \
-H "X-API-KEY: $RESELLER_API_KEY" \
-H "Accept: application/json"
Sample response (200 OK)
{
"success": true,
"message": "DNS record deleted successfully.",
"data": {
"records": []
}
}
Transfer lock, privacy and EPP codes
Protect a domain from unauthorised transfers and manage Whois privacy where the extension supports it.
Path parameters
domain
required portal domain ID or full domain name
Good to know
Only some extensions expose an Auth/EPP code. Others return an unsupported-action message.
Never store or log the code, and never print it in a public page.
cURL
curl -X POST "https://reseller.co.tz/api/v1/domains/{domain}/epp-code" \
-H "X-API-KEY: $RESELLER_API_KEY" \
-H "Accept: application/json"
Sample response (200 OK)
{
"success": true,
"message": "EPP code requested successfully.",
"data": {
"epp_code": "sample-auth-code"
}
}
Path parameters
domain
required portal domain ID or full domain name
Body parameters
epp_code
required string 8-128 characters
cURL
curl -X PUT "https://reseller.co.tz/api/v1/domains/{domain}/epp-code" \
-H "X-API-KEY: $RESELLER_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"epp_code":"new-sample-auth-code"}'
Request body
{
"epp_code": "new-sample-auth-code"
}
Sample response (200 OK)
{
"success": true,
"message": "EPP code updated successfully.",
"data": []
}
Path parameters
domain
required portal domain ID or full domain name
cURL
curl -X GET "https://reseller.co.tz/api/v1/domains/{domain}/lock" \
-H "X-API-KEY: $RESELLER_API_KEY" \
-H "Accept: application/json"
Sample response (200 OK)
{
"success": true,
"message": "Domain lock status loaded successfully.",
"data": {
"locked": true
}
}
Path parameters
domain
required portal domain ID or full domain name
Body parameters
Good to know
A locked domain cannot be transferred away until the lock is removed.
cURL
curl -X PUT "https://reseller.co.tz/api/v1/domains/{domain}/lock" \
-H "X-API-KEY: $RESELLER_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"locked":true}'
Request body
Sample response (200 OK)
{
"success": true,
"message": "Domain lock updated successfully.",
"data": {
"locked": true
}
}
Path parameters
domain
required portal domain ID or full domain name
cURL
curl -X GET "https://reseller.co.tz/api/v1/domains/{domain}/privacy" \
-H "X-API-KEY: $RESELLER_API_KEY" \
-H "Accept: application/json"
Sample response (200 OK)
{
"success": true,
"message": "Whois privacy status loaded successfully.",
"data": {
"enabled": false
}
}
Path parameters
domain
required portal domain ID or full domain name
Body parameters
Good to know
Many country extensions, including .tz domains, do not offer Whois privacy.
cURL
curl -X PUT "https://reseller.co.tz/api/v1/domains/{domain}/privacy" \
-H "X-API-KEY: $RESELLER_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"enabled":true}'
Request body
Sample response (200 OK)
{
"success": true,
"message": "Whois privacy updated successfully.",
"data": {
"enabled": true
}
}
SMS sending and logs
Send SMS from your prepaid SMS wallet and review every accepted or failed gateway attempt.
Body parameters
recipient
required phone number, for example 0712345678 or 255712345678
message
required plain-text message, max 918 characters
sender_id
required one of your approved sender IDs
client_reference
optional string max:120, returned in your own tracking records
Good to know
The wallet is charged per GSM-7 or Unicode segment only after the gateway accepts the message.
Failed attempts are logged with a sanitised error and are not charged.
SMS sending must be enabled by an administrator before this endpoint can be used.
cURL
curl -X POST "https://reseller.co.tz/api/v1/sms/send" \
-H "Authorization: Bearer $RESELLER_SMS_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"recipient":"0712345678","sender_id":"SHOP","message":"Your order is ready for collection."}'
Request body
{
"recipient": "0712345678",
"sender_id": "SHOP",
"message": "Your order is ready for collection."
}
Sample response (200 OK)
{
"success": true,
"message": "SMS accepted successfully.",
"data": {
"recipient": "255712345678",
"sender_id": "SHOP",
"segments": 1,
"credits_charged": 1,
"status": "accepted",
"provider_message_id": "msg_123"
}
}
Query parameters
status
optional accepted or failed
source
optional portal, api or admin
purpose
optional campaign, test, api, quick, marketing or provider_test
per_page
optional integer 1-100, default 25
Good to know
Only attempts owned by the authenticated reseller account are returned.
API send attempts appear with source=api.
cURL
curl -X GET "https://reseller.co.tz/api/v1/sms/logs" \
-H "Authorization: Bearer $RESELLER_SMS_TOKEN" \
-H "Accept: application/json"
Sample response (200 OK)
{
"success": true,
"message": "SMS logs loaded successfully.",
"data": {
"logs": [
{
"id": 1,
"status": "accepted",
"source": "api",
"purpose": "api",
"recipient": "255712345678",
"sender_id": "SHOP",
"message_preview": "Your order is ready for collection.",
"segments": 1,
"credits_charged": 1,
"provider_message_id": "msg_123",
"error": null,
"created_at": "2026-10-02T08:00:00+00:00"
}
],
"pagination": {
"current_page": 1,
"per_page": 25,
"total": 1,
"last_page": 1
}
}
}
Query parameters
provider_message_id
optional provider message id returned by the sending API
status
optional accepted or failed
delivery_status
optional pending, submitted, delivered, undelivered or failed
from
optional ISO date/time lower bound
to
optional ISO date/time upper bound
per_page
optional integer 1-100, default 25
Good to know
Only attempts owned by the authenticated reseller account are returned.
delivery_status=submitted means the gateway accepted the message; delivered and undelivered are populated when provider delivery reports are connected.
cURL
curl -X GET "https://reseller.co.tz/api/v1/sms/delivery-reports" \
-H "Authorization: Bearer $RESELLER_SMS_TOKEN" \
-H "Accept: application/json"
Sample response (200 OK)
{
"success": true,
"message": "Delivery reports loaded successfully.",
"data": {
"delivery_reports": [
{
"id": 1,
"provider_message_id": "msg_123",
"recipient": "255712345678",
"sender_id": "SHOP",
"status": "accepted",
"delivery_status": "submitted",
"segments": 1,
"submitted_at": "2026-10-02T08:00:00+00:00",
"delivered_at": null,
"error": null
}
],
"pagination": {
"current_page": 1,
"per_page": 25,
"total": 1,
"last_page": 1
}
}
}
Data schemas
Request objects reused by the endpoints above. All fields are strings unless stated otherwise.
Contact
name
required string max:120
organization
required string max:120
address1
required string max:255
city
required string max:120
state
required string max:120
postcode
required string max:30
country
required ISO 3166-1 alpha-2 code, for example TZ (Tanzania) or ZA (South Africa)
phone
required string max:40, include the country code when possible
email
required valid email address max:255
Dns record
type
required one of A, AAAA, CNAME, MX, TXT, SRV, CAA, NS
name
required string max:253. Use @ for the root, * for a wildcard, or a label such as www
value
required string max:1000. A takes IPv4, AAAA takes IPv6, CNAME/MX/SRV/NS take a hostname
ttl
optional integer 60-86400, default 14400
priority
optional integer 0-65535, commonly used for MX and SRV
weight
optional integer 0-65535, commonly used for SRV
port
optional integer 1-65535, commonly used for SRV
flag
optional integer 0-255, commonly used for CAA
tag
optional one of issue, issuewild, iodef, commonly used for CAA
replace_existing
optional boolean, true to overwrite an existing record with the same type and name
Best practices
Call the API from your own backend only. Never ship the key inside browser JavaScript or a public mobile app bundle.
Store the key in an environment variable or secret manager, and whitelist the server IP in the reseller portal.
Show customers the friendly message; keep raw responses and technical detail in your own logs.
Never log or display Auth/EPP codes.
Billable calls are not idempotent, so add your own retry guard before repeating a registration or renewal.
After a transfer, poll POST /domains/{domain}/sync instead of assuming the move finished instantly.
Countries must be ISO 3166-1 alpha-2 codes: Tanzania TZ, Kenya KE, South Africa ZA.
Legacy API Support
Older integrations can continue posting action-based requests to the legacy endpoint. New projects should use /api/v1 because it is easier to validate, audit, and extend.
https://reseller.co.tz/api
Legacy Request
{
"action": "registerDomain",
"domainName": "example.co.tz",
"period": 1,
"nameservers": ["ns1.example.co.tz", "ns2.example.co.tz"],
"registrantInfo": {
"name": "Jane Doe",
"organization": "Jane Doe Ltd",
"address1": "123 Registry Road",
"city": "Dar es Salaam",
"state": "Dar es Salaam",
"postcode": "11101",
"country": "TZ",
"phone": "+255.754123456",
"email": "jane@example.co.tz"
}
}
Legacy Response
{
"status": "success",
"message": "Domain registered successfully.",
"data": {
"domain": {
"domain_name": "example.co.tz",
"status": "active"
}
},
"meta": {
"balance_before": 100000,
"balance_after": 65000
}
}
Action
Purpose
checkDomainCheck domain availability and pricing.
getDomainInfoFetch domain information.
registerDomainRegister a domain.
renewDomainRenew a domain.
transferDomainSubmit a domain transfer.
getNameservers / updateNameserversRead or update nameservers.
getWhois / updateWhoisRead or update Whois contacts.
getEPPCodeRequest the current EPP/Auth code.
provisionDns / cancelDnsEnable or cancel DNS management.
getDnsRecords / addDnsRecord / deleteDnsRecordManage DNS records.
getBalanceFetch current reseller balance.
Status Codes
Code
Meaning
200
Request completed successfully.
201
The resource was created or a billable action completed successfully.
401
The API key is missing, revoked, or invalid.
403
The API key is valid but the calling IP is not whitelisted, or the account is not allowed to use the API.
404
The domain, record, or resource does not belong to the authenticated reseller account.
422
Validation failed, the balance is too low, the action is unsupported for this extension, or the registry could not complete the request.
429
Too many requests. Slow down and retry later.
500
Unexpected server error. Retry later and contact support if it continues.