Quick start
Create your key on the API page of the reseller panel.
GET /products returns products with your reseller price and the list price.
POST /orders creates the order and charges your balance.
Your first request
curl https://www.datassl.com/api/reseller/products \ -H "X-API-Key: YOUR_API_KEY"
Base URL: https://www.datassl.com/api/reseller. All requests and responses are JSON. Successful responses contain "success": true; errors contain "success": false and an "error" message.
Authentication
Send your API key with every request in one of two ways:
X-API-Key: YOUR_API_KEY Authorization: Bearer YOUR_API_KEY
- Use the key on the server side only; never put it in a browser or mobile app.
- To test connectivity without authentication, use
GET /ping. If you send a key, the response also includesapi_key_valid. - Limit: 600 requests per minute. When exceeded you get
429with aRetry-Afterheader; wait one minute.
Sell on your site
To sell on your own site you only need three things: pull the product list, add your margin on top of your reseller price, and place the order through the API when your customer pays.
pricing is the reseller price you pay (year → price). list_pricing is our retail price. Amounts are USD, excluding VAT; pricing_detail also gives the same prices in your account currency.Example: pull products and price them with a 30% margin (PHP)
<?php
$apiBase = 'https://www.datassl.com/api/reseller';
$apiKey = 'YOUR_API_KEY';
$margin = 30; // your margin, %
function datassl($method, $path, $body = null) {
global $apiBase, $apiKey;
$ch = curl_init($apiBase . $path);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_HTTPHEADER => ['X-API-Key: ' . $apiKey, 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => $body ? json_encode($body) : null,
CURLOPT_TIMEOUT => 60,
]);
$res = json_decode(curl_exec($ch), true);
curl_close($ch);
return $res;
}
// 1) Pull products (caching a few times a day is enough)
$list = datassl('GET', '/products');
foreach ($list['products'] as $p) {
foreach ($p['pricing'] as $years => $cost) { // year => your reseller price (USD)
$sell = round($cost * (1 + $margin / 100), 2); // your selling price
printf("%s | %d %s | %s %.2f → %s %.2f\n", $p['name'], $years,
'yr', 'cost', $cost, 'sell', $sell);
}
}
// 2) When your customer pays, place the order
$order = datassl('POST', '/orders', [
'product_id' => 12,
'domain' => 'example.com',
'period' => 12, // months: 12, 24 or 36
]);
echo $order['success'] ? 'Order #' . $order['order_id'] : $order['error'];- Do not fetch prices on every page view; refresh them periodically and store them in your own database.
- The order is charged at the reseller price at order time; to re-check the price before taking payment, call
GET /products/{id}. - If you prefer not to write code, the ready-made modules do the same job.
Products and prices
| Request | Tavsif |
|---|---|
GET /products | Active products in your reseller group. Filters: Brand, Type, tasdiqlash. Add include=acme for automatic SSL (ACME) products. |
GET /products/{id} | Single product: 1–5 year prices, SAN (extra domain) and wildcard SAN prices, description and features. |
Example response (shortened)
{
"success": true,
"count": 1,
"products": [{
"id": 12,
"name": "Sectigo PositiveSSL",
"brand": "Sectigo",
"validation_type": "DV",
"base_currency": "USD",
"tax_rate": 20,
"pricing": { "1": 7.20, "2": 13.10, "3": 18.90 },
"list_pricing": { "1": 9.99, "2": 17.99, "3": 25.99 },
"max_years": 3,
"san_enabled": false
}]
}- Keys in
pricingare years. Sendperiodin months when ordering: 1 year = 12. - For SAN products,
san.reseller_pricesin/products/{id}is the price per extra domain. - Only products assigned to your reseller group are listed.
Placing orders
At order time the amount (including VAT) is charged to your balance and a paid invoice is created. You do not need a separate payment call.
curl -X POST https://www.datassl.com/api/reseller/orders \
-H "X-API-Key: YOUR_API_KEY" -H "Content-Type: application/json" \
-d '{"product_id": 12, "domain": "example.com", "period": 12}'| Field | Tavsif |
|---|---|
product_id * | Product id (GET /products). |
domain * | Main domain. Not needed for products without a domain such as code signing. If empty, the CSR CN is used. |
period | Months: 12, 24, 36. Default 12. The charge is calculated for the chosen period. |
san_count, san_wildcard_count | Number of extra domains and extra wildcard domains (max 250). |
usb_token | Code signing only: if true, a paid USB token is added (see Code signing orders). |
csr | Optional. If sent, the order goes straight to validation; otherwise complete it later with /ssl/configure. |
dcv_method, approver_email | Domain validation method: email, http, https, dns. Approver address for the email method. |
san_domains | Extra domains, comma separated. |
admin_*, organization, org_* | Contact and organization details (required for OV/EV): admin_firstname, admin_lastname, admin_email, admin_phone, org_address, org_city, org_country… |
Response (shortened)
{
"success": true,
"order_id": 1534,
"order_number": "ORD-2026-1534",
"subtotal": 7.20, "tax_amount": 1.44, "total": 8.64,
"status": "pending_configuration",
"payment_status": "paid",
"new_balance": 191.36,
"invoice_number": "INV-2026-2011"
}Order statuses
| Holat | Maʼnosi |
|---|---|
pending_configuration | Paid, waiting for CSR and validation details (/ssl/configure). |
Processing | At the certificate authority; domain/organization validation in progress. |
Active | Certificate issued and ready to download. |
Cancelled | Cancelled; the amount was refunded to your balance. |
List orders with GET /orders (filters: Status, domain, limit, offset); a single order with GET /orders/{id}.
Code signing orders
Code signing certificates are configured differently from SSL: there is no domain, CSR or domain validation (DCV). The certificate is issued to a company and the certificate authority validates the company.
curl -X POST https://www.datassl.com/api/reseller/orders \
-H "X-API-Key: YOUR_API_KEY" -H "Content-Type: application/json" \
-d '{"product_id": 343, "period": 12,
"organization": "Example Software Ltd.", "org_address": "...", "org_city": "Istanbul", "org_country": "TR", "org_phone": "+90 ...",
"admin_firstname": "Ada", "admin_lastname": "Yilmaz", "admin_email": "ada@example.com", "admin_phone": "+90 ..."}'domainvacsrare not sent. Organization (organization,org_*) and contact (admin_*) details must be complete.- With cloud code signing, the key is kept in the certificate authority's cloud HSM; no USB token is shipped. Company validation and signing account activation depend on the certificate authority; track the status with GET /orders/{id}.
- USB token (optional, paid): for code signing products delivered on a physical token (e.g. Sectigo, DigiCert), add
"usb_token": trueto the order; the token fee is added to the order total and we ship the token. Theusb_token_pricefield in the product response shows the token price; if it isnull, no token is offered for that product and sendingusb_tokenreturns 400. If you have your own token or HSM, do not sendusb_token. - Certum products are sold for 1 year only (period: 12).
- The 200-day rule does not apply to code signing; the certificate is valid for the purchased term.
Documents and validation status
The certificate authority may ask for documents for company validation. Upload them through the API; documents are stored securely on our side and forwarded to the certificate authority.
curl -X POST https://www.datassl.com/api/reseller/orders/1534/documents -H "X-API-Key: YOUR_API_KEY" -F "type=company" -F "file=@trade-register.pdf" curl https://www.datassl.com/api/reseller/orders/1534/documents -H "X-API-Key: YOUR_API_KEY"
Type:Company(company document),identity(authorised person ID),authority(authorisation letter / signature circular),other. PDF, JPG or PNG; max 10 MB per file.- To send as JSON, use
{"type":"company","file_name":"x.pdf","content_base64":"..."}. - The
GETresponse returnsdocuments(send status of each document) andverifications(validation steps and states at the certificate authority).
Configuration and validation
If you did not send a CSR with the order, send the CSR and validation method in this step. Then poll the status and download the certificate once issued.
curl -X POST https://www.datassl.com/api/reseller/ssl/configure \
-H "X-API-Key: YOUR_API_KEY" -H "Content-Type: application/json" \
-d '{"order_id": 1534, "csr": "-----BEGIN CERTIFICATE REQUEST-----...", "dcv_method": "dns"}'| Request | Tavsif |
|---|---|
POST /csr/decode | Decodes a CSR: domain, organization, key size. Useful to check before ordering. |
POST /ssl/configure | order_id and csr required; dcv_method, approver_email, admin_*, organization, san_domains, webserver_type optional. |
GET /ssl/{order_id} | Live status and validation details (DNS record, HTTP file or approver email). |
GET /certificate/{order_id}/download | Certificate (certificate_pem) and intermediate chain (ca_bundle). We do not hold the private key; it stays on the server where you created the CSR. |
Certificate actions
| Request | Body | Tavsif |
|---|---|---|
POST /ssl/resend-validation | {"order_id": 1534} | Resends the validation email. |
POST /ssl/change-dcv | {"order_id": 1534, "dcv_method": "http"} | Changes the validation method. |
POST /ssl/reissue | {"order_id": 1534, "csr": "..."} | Free reissue with a new CSR. |
PUT /orders/{id} | {"action": "cancel", "reason": "..."} | Cancels before the certificate is issued; the amount is refunded to your balance. |
next_reissue_at in the order response is the next reissue date. This rule applies to SSL/TLS certificates only; code signing certificates are valid for the purchased term and need no reissue.Balance, invoices, account
| Request | Tavsif |
|---|---|
GET /balance | Balance, credit limit and the last 10 transactions. |
GET /invoices, /invoices/{id} | Invoices. Filters: status, limit (max 100), offset. |
GET /account | Account details, your reseller group and order count. |
GET /stats | Order and spending summaries. |
Balance top-ups are done in the panel. If the balance is insufficient, the order is rejected with error 402 and nothing is charged.
Errors and limits
Every error response has a fixed error_code, a suggested fix (hint) and a request_id. Base your logic on error_code, not the message text: messages may change, codes do not. Include the request_id in support tickets (it is also returned in the X-Request-Id header). hint is in Turkish or English according to Accept-Language; you can also pass ?lang=tr.
{
"success": false,
"error": "Yetersiz bakiye. Sipariş tutarı: USD 49.00. Mevcut bakiye: USD 12.50. Lütfen kredi yükleyin.",
"error_code": "INSUFFICIENT_BALANCE",
"http_status": 402,
"hint": "Top up your balance in the reseller panel (Account → Add funds), then retry.",
"request_id": "3f9a1c07b2de",
"docs": "https://www.datassl.com/en/api-docs#err-insufficient-balance"
}$r = json_decode($body, true);
if (empty($r['success'])) {
switch ($r['error_code'] ?? '') {
case 'INSUFFICIENT_BALANCE': /* show a top-up warning */ break;
case 'CSR_INVALID': /* ask the customer for a new CSR */ break;
case 'INTERNAL_ERROR': /* retry later */ break;
}
error_log('DATASSL ' . $r['error_code'] . ' ' . $r['error'] . ' ref=' . $r['request_id']);
}Error codes
Authentication and access
| Code | HTTP | Meaning and fix |
|---|---|---|
AUTH_MISSING | 401 | API key missing Send the X-API-Key header or Authorization: Bearer <key>. In the module, check that the API key field is filled in. |
AUTH_INVALID | 401 | API kaliti yaroqsiz yoki API ruxsati oʻchirilgan Copy the key again from the reseller panel (Account → API) with no leading/trailing spaces. If you regenerated the key, update it in the module too. If API access is disabled, contact us. |
RESELLER_GROUP_MISSING | 403 | No reseller group assigned Your account has no reseller group, so you cannot buy products. Contact us to have a group assigned. |
Request
| Code | HTTP | Meaning and fix |
|---|---|---|
ENDPOINT_NOT_FOUND | 404 | Unknown endpoint Check the path and method (GET/POST). Send GET /api/reseller for the endpoint list. Update the module if it is an old version. |
METHOD_NOT_ALLOWED | 405 | Method not allowed Use the method shown in the docs for this endpoint (e.g. POST /orders to create an order). |
MISSING_FIELD | 400 | Required field missing Send the field named in the error message (product_id, domain, order_id, csr, contact_email…). For a JSON body, use the Content-Type: application/json header. |
VALIDATION_ERROR | 422 | Invalid value Fix the value of the field in the message to match the format in the docs. |
INVALID_ACTION | 400 | Invalid action Send a supported action (e.g. action: cancel). |
Products and orders
| Code | HTTP | Meaning and fix |
|---|---|---|
RESTRICTED_REGION | 403 | Certificates are not issued for this country or domain Certificate authorities do not issue certificates for Russia, Belarus, Iran, Cuba, North Korea, Syria or Venezuela, or for those countries' domain extensions. Use a different domain. |
PRODUCT_NOT_FOUND | 404 | Mahsulot topilmadi The product is disabled or not in your reseller group. Get the current list with GET /products; run "Refresh / import products" in the module. |
ORDER_NOT_FOUND | 404 | Buyurtma topilmadi The order id is wrong or belongs to another account. Check the order id stored on the service in the module. |
INVOICE_NOT_FOUND | 404 | Hisob-faktura topilmadi Check the invoice id in the GET /invoices list. |
ORDER_STATE_INVALID | 409 | Order is not in a valid state for this action Check the order status with GET /orders/{id}. Cancel works only on pending orders; reissue only on active certificates. |
ALREADY_CONFIGURED | 409 | Order already configured A CSR was already submitted for this order. Track it with GET /orders/{id}; use reissue to change it. |
ALREADY_PAID | 409 | Order already paid No further action is needed. |
USB_TOKEN_NOT_OFFERED | 400 | USB token not offered for this product Send usb_token only for code signing products whose usb_token_price is set. Do not send it for cloud products. |
CERTIFICATE_NOT_READY | 404 | Certificate not ready yet The certificate can be downloaded once validation is complete. Track it with GET /orders/{id} and make sure the DCV step is done. |
NOT_SUPPORTED | 501 | Action not supported Create a new order to renew (POST /orders). For actions not supported for this product, open a support ticket. |
Toʻlov
| Code | HTTP | Meaning and fix |
|---|---|---|
INSUFFICIENT_BALANCE | 402 | Insufficient balance Top up your balance in the reseller panel (Account → Add funds), then retry. The module does not retry automatically. |
CREDIT_LIMIT_EXCEEDED | 402 | Credit limit exceeded Pay your open invoices or contact us to raise your credit limit. |
PAYMENT_REQUIRED | 402 | Payment required first Pay the order first (POST /payments or the reseller panel), then configure it. |
PAYMENT_FAILED | 500 | Payment could not be processed Retry in a few minutes; if it persists, contact us with the request_id. |
SSL, code signing and validation
| Code | HTTP | Meaning and fix |
|---|---|---|
CSR_INVALID | 400 | Invalid CSR The CSR must start with "-----BEGIN CERTIFICATE REQUEST-----" and be copied completely. Use at least a 2048-bit RSA or an ECC key; the CN must match the domain. You can check it with POST /csr/decode. |
DCV_METHOD_INVALID | 400 | Invalid DCV method Valid methods: email, http, https, dns. For email, send approver_email. |
CODESIGN_ORDER_NOT_FOUND | 404 | Code signing order not found Document upload is only for code signing orders; check the order id. |
DOCUMENT_INVALID | 422 | Document rejected Send PDF, JPG or PNG, max 10 MB. content_base64 must be valid base64. |
SUBSCRIPTION_ERROR | 422 | Subscription request failed Fix the reason in the message (e.g. contact_email). If the subscription is not found, check the order id. |
Server
| Code | HTTP | Meaning and fix |
|---|---|---|
PROVIDER_ERROR | 502 | The certificate authority rejected the request Check the reason in the message (e.g. domain, CSR, organization details). Fix and retry; if it persists, contact us with the request_id. |
INTERNAL_ERROR | 500 | Server xatosi Retry in a few minutes. If it persists, open a support ticket with the request_id so we can trace it. |
HTTP statuses
| HTTP | Maʼnosi |
|---|---|
| 400 | Missing or invalid field. |
| 401 | API key missing, wrong, or API access disabled. |
| 402 | Insufficient balance or credit limit; or the order is unpaid. |
| 403 | No access to this product or order (e.g. not in your reseller group). |
| 404 | Record or endpoint not found. |
| 405 | This endpoint does not support this HTTP method. |
| 422 | Data is not valid (e.g. invalid domain for an ACME product). |
| 429 | Rate limit exceeded; wait for Retry-After. |
| 500, 502 | Temporary error on our side or at the certificate authority; retry shortly. |
Ready-made modules
Modules are downloaded from the reseller panel with your API key embedded; you do not need to enter the key again after installing.
WHMCS
- Imports products into WHMCS in one click and adds your margin as a percentage.
- Orders, CSR, validation, cancellation and reissue are automatic.
- Install: extract the zip in the WHMCS root and activate "DATASSL" under Addon Modules.
WiseCP
- Links your WiseCP products to DATASSL products; orders are created automatically.
- CSR, validation, certificate download and cancellation from the client area.
- Install: extract the zip in the WiseCP root and enable DATASSL under Product Modules.
WordPress / WooCommerce
- Adds an SSL product type to WooCommerce; the order is placed automatically after payment.
- CSR entry and certificate download in the customer account.
- Install: Plugins › Add New › Upload Plugin and upload the zip.
To download, sign in with your reseller account and create an API key first.
All endpoints
| Usul | Path | Tavsif |
|---|---|---|
| GET | /ping | Connectivity test (no key needed) |
| GET | /products | Products and reseller prices |
| GET | /products/{id} | Product detail, 1–5 year and SAN prices |
| POST | /orders | Place an order (paid from balance) |
| GET | /orders | Buyurtmalar |
| GET | /orders/{id} | Order detail |
| PUT | /orders/{id} | Cancel: {"action":"cancel"} |
| GET | /orders/{id}/acme | Automatic SSL (ACME) details |
| GET | /orders/{id}/documents | Code signing documents and validation status |
| POST | /orders/{id}/documents | Upload a code signing document |
| POST | /csr/decode | CSRʼni dekodlash |
| POST | /ssl/configure | Send CSR and validation details |
| GET | /ssl/{order_id} | Live status and validation details |
| POST | /ssl/resend-validation | Tekshiruv xatini qayta yuborish |
| POST | /ssl/change-dcv | Change validation method |
| POST | /ssl/reissue | Qayta chiqarish |
| GET | /certificate/{id} | Certificate details |
| GET | /certificate/{id}/download | Certificate and chain |
| GET | /balance | Balance and transactions |
| GET | /invoices | Hisob-fakturalar |
| GET | /account | Account details |
| GET | /stats | Statistika |
Changelog
API changes are published here. Changes that may affect your integration are called out.
Important: restricted countries and domains
- For countries and domain extensions that certificate authorities do not serve (Russia, Belarus, Iran, Cuba, North Korea, Syria, Venezuela), POST /orders and POST /ssl/configure return 403 with the RESTRICTED_REGION code.
Error codes and troubleshooting
- Every error response has error_code (fixed code), hint (suggested fix), http_status, request_id and docs fields. The error field is still text; existing integrations are not affected.
- An X-Request-Id header on every response; include this value in support tickets.
- Server errors no longer expose internal details; they are logged under the request_id.
- GET /certificate/{id} also returns the PEM content when the certificate is ready (certificate, certificate_pem, ca_bundle); a certificate field was added to the /download response.
USB token for code signing
- New: usb_token (true/false) in POST /orders — adds a paid USB token to code signing products delivered on a physical token; the fee is added to the order total and we ship the token.
- usb_token_price field in product responses: the token price, or null for products without a token option.
- usb_token and usb_token_price fields in the order response.
Code signing documents
- New: GET /orders/{id}/documents — uploaded documents and the status of validation steps at the certificate authority.
- New: POST /orders/{id}/documents — upload documents to a code signing order (PDF, JPG, PNG; max 10 MB). Fields: type (company, identity, authority, other), file_name, content_base64; or multipart "file".
Order pricing and module compatibility
- Multi-year orders are charged for the selected period; SAN charges are calculated per period.
- Legacy module calls are supported: POST /orders/{id}/cancel, /reissue, /resend-validation, /change-dcv; period may also be sent in years (1–5); wildcard_san_count and dns_names field names are accepted.
- Unknown endpoints now return 404 (previously a success response).
- The domain field is not required for code signing products.
- Cost fields were removed from the GET /products/{id} response.