🔑 Authentication
Bearer Token (Laravel Sanctum)
This API uses token-based authentication powered by Laravel Sanctum. Obtain a token via the login endpoint, then include it in all subsequent requests using the Authorization header.
How it works
- Send your credentials to
POST /api/v1/auth/login
- Receive a
token in the response
- Include the token in all subsequent requests:
Header
Authorization: Bearer your-api-token-here
Token Abilities
Each token is scoped with specific abilities: cpid:generate, cpid:read, credits:read, payments:read, payments:create, profile:read, profile:update
⏱ Rate Limiting
Request Limits
API requests are rate-limited to prevent abuse. When you exceed the limit, you will receive a 429 Too Many Requests response.
| Endpoint | Limit | Window |
| POST /auth/login | 10 requests | 1 minute |
| POST /services/execute | 100 requests | 1 minute |
| POST /payments/request | 5 requests | 1 minute |
| All other endpoints | 60 requests | 1 minute |
⚠ Error Codes
| Code | Status | Description |
| 200 | OK | Request succeeded |
| 201 | Created | Resource created successfully |
| 202 | Accepted | Request accepted for processing (queued) |
| 401 | Unauthorized | Missing or invalid authentication token |
| 402 | Payment Required | Insufficient credits to complete the operation |
| 403 | Forbidden | Account suspended or license inactive |
| 404 | Not Found | Resource does not exist or does not belong to you |
| 409 | Conflict | Duplicate record detected (use force=true to override) |
| 422 | Unprocessable Entity | Validation failed — check the errors object |
| 429 | Too Many Requests | Rate limit exceeded — wait and retry |
| 502 | Bad Gateway | External CPID service unavailable |
🔐 Authentication
Authenticate a user and receive a Sanctum API token. Previous tokens for the same device name are automatically revoked.
Request Headers
| Header | Value |
| Content-Type | application/json |
| Accept | application/json |
Request Body
| Parameter | Type | Required | Description |
| email | string | Required | User email address |
| password | string | Required | User password |
| device_name | string | Optional | Device identifier for the token. Default: api-client. Max 255 characters. |
Response Examples
200 OK
{
"success": true,
"data": {
"token": "1|a3bK9xT2mNpQ7rY...",
"token_type": "Bearer",
"user": {
"id": 1,
"name": "John Doe",
"email": "[email protected]",
"role": "customer",
"balance": 125.50,
"has_api_access": true,
"parent_id": null,
"license_status": "active",
"license_expiry": "2026-12-31T23:59:59+00:00",
"is_active": true,
"created_at": "2025-01-15T10:30:00+00:00"
}
},
"message": "Login successful."
}
401 Unauthorized
{
"success": false,
"message": "Invalid credentials."
}
403 Forbidden
{
"success": false,
"message": "Your account has been suspended. Please contact the administrator."
}
Revoke the current access token, effectively logging the user out of the current session.
Request Headers
| Header | Value |
| Authorization | Bearer {token} |
| Accept | application/json |
Response
200 OK
{
"success": true,
"data": null,
"message": "Logged out successfully."
}
Retrieve the authenticated user's information including license and credit data.
Request Headers
| Header | Value |
| Authorization | Bearer {token} |
| Accept | application/json |
Response
200 OK
{
"success": true,
"data": {
"id": 1,
"name": "John Doe",
"email": "[email protected]",
"role": "customer",
"balance": 125.50,
"has_api_access": true,
"parent_id": null,
"license_status": "active",
"license_expiry": "2026-12-31T23:59:59+00:00",
"is_active": true,
"created_at": "2025-01-15T10:30:00+00:00"
},
"message": "User data retrieved successfully."
}
UserResource Fields
role — User role (string): customer, reseller, admin
balance — Account balance in USD (float)
has_api_access — Whether user has API access (boolean)
parent_id — Parent reseller ID, null if none (nullable integer)
👤 Profile
Retrieve the authenticated user's profile with credit balance and license information.
Request Headers
| Header | Value |
| Authorization | Bearer {token} |
| Accept | application/json |
Response
200 OK
{
"success": true,
"data": {
"id": 1,
"name": "John Doe",
"email": "[email protected]",
"credits": 42,
"license_status": "active",
"license_expiry": "2026-12-31T23:59:59+00:00",
"is_active": true,
"created_at": "2025-01-15T10:30:00+00:00"
},
"message": "Profile retrieved successfully."
}
Update the authenticated user's profile. Currently only the name field can be updated.
Request Headers
| Header | Value |
| Authorization | Bearer {token} |
| Content-Type | application/json |
| Accept | application/json |
Request Body
| Parameter | Type | Required | Description |
| name | string | Required | New display name. Max 255 characters. |
Response
200 OK
{
"success": true,
"data": {
"id": 1,
"name": "Jane Doe",
"email": "[email protected]",
"credits": 42,
"license_status": "active",
"license_expiry": "2026-12-31T23:59:59+00:00",
"is_active": true,
"created_at": "2025-01-15T10:30:00+00:00"
},
"message": "Profile updated successfully."
}
💳 Credits
Retrieve the current user's credit balance along with license status information.
Request Headers
| Header | Value |
| Authorization | Bearer {token} |
| Accept | application/json |
Response
200 OK
{
"success": true,
"data": {
"credits": 42,
"license_active": true,
"license_expiry": "2026-12-31T23:59:59+00:00"
},
"message": "Credit balance retrieved successfully."
}
List all active credit packages with their pricing information in both TRY and USD.
Request Headers
| Header | Value |
| Authorization | Bearer {token} |
| Accept | application/json |
Response
200 OK
{
"success": true,
"data": [
{
"id": 1,
"name": "Starter Pack",
"credits": 10,
"price": 150.00,
"price_usd": 5.00,
"price_per_credit": 15.00,
"price_per_credit_usd": 0.50,
"is_active": true
},
{
"id": 2,
"name": "Pro Pack",
"credits": 50,
"price": 600.00,
"price_usd": 20.00,
"price_per_credit": 12.00,
"price_per_credit_usd": 0.40,
"is_active": true
}
],
"message": "Credit packages retrieved successfully."
}
Retrieve the current unit pricing for credits. Returns the cost of a single credit in both TRY and USD currencies, along with the default currency setting.
Request Headers
| Header | Value |
| Authorization | Bearer {token} |
| Accept | application/json |
Response
200 OK
{
"success": true,
"data": {
"price_per_credit_try": 15.00,
"price_per_credit_usd": 0.50,
"currency_default": "TRY"
},
"message": "Pricing information retrieved successfully."
}
🛡 CPID Operations
Execute a CPID generation service. Validates input, resolves pricing, deducts balance, and generates CPID data. Supports cache hit for duplicate inputs.
Important Notes
• Balance is deducted based on the service/device pricing tier.
• If the external service fails, the balance is automatically refunded.
• IMEI numbers must start with 86 and pass Luhn checksum validation.
• Duplicate inputs (same product_code + cpu_id + imei1 + imei2) are served from cache instantly.
Request Headers
| Header | Value |
| Authorization | Bearer {token} |
| Content-Type | application/json |
| Accept | application/json |
Request Body
| Parameter | Type | Required | Description |
| service_slug | string | Required | Service slug. e.g. cpid-generator |
| sub_service_slug | string | Required | Sub-service slug. e.g. mtk-cpid, qualcomm-cpid, qualcomm-cpid-new |
| device_id | integer | Optional | Device ID for device-specific pricing and validation. |
| input_data.product_code | string | Required | Product code. e.g. charoite, begonia |
| input_data.cpu_id | string | Required | CPU identifier / HWID. Max 34 chars. |
| input_data.imei1 | string | Required | Primary IMEI. 15 digits, must start with 86 and pass Luhn validation. |
| input_data.imei2 | string | Optional | Secondary IMEI. 15 digits, must start with 86 and pass Luhn validation if provided. |
Response Examples
202 Accepted
{
"success": true,
"data": {
"record_id": 157,
"message": "CPID generated successfully.",
"data": {
"created_criticaldata": "...binary data...",
"product_code": "charoite"
}
},
"message": "Service executed successfully."
}
409 Conflict (Duplicate)
{
"success": false,
"message": "Duplicate detected: IMEI 1 already exists in your records. Send force=true to proceed anyway.",
"errors": {
"duplicate_field": "IMEI 1"
}
}
402 Payment Required
{
"success": false,
"message": "Insufficient credits. Please purchase more credits."
}
422 Validation Error
{
"success": false,
"message": "Validation failed.",
"errors": {
"imei1": ["IMEI 1 must be exactly 15 characters."],
"product_code": ["The product code field is required."]
}
}
Retrieve a paginated list of the authenticated user's CPID generation history. Supports filtering by status and date range.
Query Parameters
| Parameter | Type | Required | Description |
| status | string | Optional | Filter by status: pending, processing, completed, or failed |
| date_from | string | Optional | Start date filter. Format: Y-m-d |
| date_to | string | Optional | End date filter. Format: Y-m-d. Must be after or equal to date_from. |
| per_page | integer | Optional | Items per page. Min: 1, Max: 100. Default: 20. |
| page | integer | Optional | Page number. Default: 1. |
Response
200 OK
{
"success": true,
"data": [
{
"id": 157,
"product_code": "sm-a155f",
"cpu_id": "A3B7C9D1E5F20018",
"imei1": "353456789012345",
"imei2": "353456789012352",
"status": "completed",
"has_data": true,
"created_at": "2026-03-22T14:30:00+00:00",
"updated_at": "2026-03-22T14:30:12+00:00"
},
{
"id": 156,
"product_code": "sm-g990b",
"cpu_id": "F1E2D3C4B5A60024",
"imei1": "861234567890123",
"imei2": null,
"status": "failed",
"has_data": false,
"created_at": "2026-03-21T09:15:00+00:00",
"updated_at": "2026-03-21T09:15:22+00:00"
}
],
"meta": {
"current_page": 1,
"last_page": 8,
"per_page": 20,
"total": 157
},
"message": "CPID history retrieved successfully."
}
Retrieve a single CPID record by its ID. Only records belonging to the authenticated user can be accessed. For completed orders, the created_criticaldata field is included in the response.
URL Parameters
| Parameter | Type | Required | Description |
| id | integer | Required | CPID record ID |
Response
200 OK
{
"success": true,
"data": {
"id": 157,
"product_code": "sm-a155f",
"cpu_id": "A3B7C9D1E5F20018",
"imei1": "353456789012345",
"imei2": "353456789012352",
"status": "completed",
"has_data": true,
"created_criticaldata": "...binary data (base64)...",
"created_at": "2026-03-22T14:30:00+00:00",
"updated_at": "2026-03-22T14:30:12+00:00"
},
"message": "Order retrieved successfully."
}
404 Not Found
{
"success": false,
"message": "No query results for model [CpidOrder]."
}
Download the generated CPID binary file (.bin) for a completed record. Only available when the record status is completed and data has been generated.
URL Parameters
| Parameter | Type | Required | Description |
| id | integer | Required | CPID record ID |
Response
Success: Binary File Download
Returns a binary stream with Content-Type: application/octet-stream. Filename format: {product_code}_{imei1}.bin
404 Not Found
{
"success": false,
"message": "No generated data available for this record."
}
💰 Payments
List all active payment methods. Config data is filtered to expose only safe display information (e.g., IBAN, wallet address) while hiding sensitive keys.
Request Headers
| Header | Value |
| Authorization | Bearer {token} |
| Accept | application/json |
Response
200 OK
{
"success": true,
"data": [
{
"id": 1,
"slug": "bank-transfer",
"name": "Bank Transfer (TRY)",
"supported_currency": "TRY",
"config": {
"account_holder": "XiaomiToolkit Ltd.",
"bank_name": "Ziraat Bankasi",
"iban": "TR00 0000 0000 0000 0000 0000 00"
},
"is_active": true
},
{
"id": 2,
"slug": "usdt-trc20",
"name": "USDT (TRC20)",
"supported_currency": "USDT",
"config": {
"wallet_address": "TXqH5g8R1k...",
"network": "TRC20"
},
"is_active": true
}
],
"message": "Payment methods retrieved successfully."
}
Retrieve a paginated list of the authenticated user's payment requests. Supports filtering by status.
Query Parameters
| Parameter | Type | Required | Description |
| status | string | Optional | Filter by status: pending, approved, or rejected |
| per_page | integer | Optional | Items per page. Min: 1, Max: 100. Default: 20. |
| page | integer | Optional | Page number. Default: 1. |
Response
200 OK
{
"success": true,
"data": [
{
"id": 23,
"reference_code": "PAY-20260322-ABC12",
"credits": 50,
"amount": 600.00,
"currency": "TRY",
"status": "pending",
"sender_name": "John Doe",
"payment_date": "2026-03-22T00:00:00+00:00",
"payment_method": {
"id": 1,
"slug": "bank-transfer",
"name": "Bank Transfer (TRY)",
"supported_currency": "TRY",
"config": { ... },
"is_active": true
},
"credit_package": {
"id": 2,
"name": "Pro Pack",
"credits": 50,
"price": 600.00,
"price_usd": 20.00,
"price_per_credit": 12.00,
"price_per_credit_usd": 0.40,
"is_active": true
},
"created_at": "2026-03-22T12:00:00+00:00",
"updated_at": "2026-03-22T12:00:00+00:00"
}
],
"meta": {
"current_page": 1,
"last_page": 2,
"per_page": 20,
"total": 23
},
"message": "Payment requests retrieved successfully."
}
Create a new payment request. You can either select a predefined credit package or specify a custom credit amount. The amount is automatically calculated based on the payment method's currency and current pricing.
Request Headers
| Header | Value |
| Authorization | Bearer {token} |
| Content-Type | application/json |
| Accept | application/json |
Request Body
| Parameter | Type | Required | Description |
| payment_method_id | integer | Required | Active payment method ID (from /payments/methods) |
| credit_package_id | integer | Conditional | Credit package ID. Required if credits is not provided. |
| credits | integer | Conditional | Custom credit amount (1-10000). Required if credit_package_id is not provided. |
| sender_name | string | Required | Name of the payment sender. Max 255 characters. |
| payment_date | string | Required | Date of the payment. Format: Y-m-d. Must be today or earlier. |
Response Examples
201 Created
{
"success": true,
"data": {
"id": 24,
"reference_code": "PAY-20260322-XYZ89",
"credits": 50,
"amount": 600.00,
"currency": "TRY",
"status": "pending",
"sender_name": "John Doe",
"payment_date": "2026-03-22T00:00:00+00:00",
"payment_method": {
"id": 1,
"slug": "bank-transfer",
"name": "Bank Transfer (TRY)",
"supported_currency": "TRY",
"config": { ... },
"is_active": true
},
"credit_package": {
"id": 2,
"name": "Pro Pack",
"credits": 50,
"price": 600.00,
"price_usd": 20.00,
"price_per_credit": 12.00,
"price_per_credit_usd": 0.40,
"is_active": true
},
"created_at": "2026-03-22T15:00:00+00:00",
"updated_at": "2026-03-22T15:00:00+00:00"
},
"message": "Payment request created successfully."
}
422 Validation Error
{
"success": false,
"message": "Validation failed.",
"errors": {
"payment_method_id": ["The payment method id field is required."],
"sender_name": ["The sender name field is required."]
}
}
Retrieve a specific payment request by ID. Includes related payment method and credit package details. Only records belonging to the authenticated user can be accessed.
URL Parameters
| Parameter | Type | Required | Description |
| id | integer | Required | Payment request ID |
Response
200 OK
{
"success": true,
"data": {
"id": 23,
"reference_code": "PAY-20260322-ABC12",
"credits": 50,
"amount": 600.00,
"currency": "TRY",
"status": "approved",
"sender_name": "John Doe",
"payment_date": "2026-03-22T00:00:00+00:00",
"payment_method": {
"id": 1,
"slug": "bank-transfer",
"name": "Bank Transfer (TRY)",
"supported_currency": "TRY",
"config": { ... },
"is_active": true
},
"credit_package": {
"id": 2,
"name": "Pro Pack",
"credits": 50,
"price": 600.00,
"price_usd": 20.00,
"price_per_credit": 12.00,
"price_per_credit_usd": 0.40,
"is_active": true
},
"created_at": "2026-03-22T12:00:00+00:00",
"updated_at": "2026-03-22T13:45:00+00:00"
},
"message": "Payment request retrieved successfully."
}
Rejected Payment Response
When a payment has been rejected, an additional rejection_reason field will be included in the response.
Rejected Payment
{
"id": 22,
"reference_code": "PAY-20260320-DEF45",
"status": "rejected",
"rejection_reason": "Payment amount does not match the expected amount.",
...
}
⚙ Services
List all available services with their sub-service counts.
Request Headers
| Header | Value |
| Authorization | Bearer {token} |
| Accept | application/json |
Response
200 OK
{
"success": true,
"data": [
{
"id": 1,
"name": "CPID",
"slug": "cpid",
"description": "CPID generation service",
"icon": "🛡",
"sub_services_count": 3
}
]
}
List all sub-services for a given service by its slug.
URL Parameters
| Parameter | Type | Required | Description |
| slug | string | Required | Service slug (e.g., cpid) |
Response
200 OK
{
"success": true,
"data": [
{
"id": 1,
"name": "Standard CPID",
"slug": "standard-cpid",
"description": "Standard CPID generation"
}
]
}
📱 Devices
List all device brands.
Request Headers
| Header | Value |
| Authorization | Bearer {token} |
| Accept | application/json |
Response
200 OK
{
"success": true,
"data": [
{
"id": 1,
"name": "Xiaomi",
"slug": "xiaomi",
"icon": "xiaomi.svg"
}
]
}
List devices with optional filtering by brand or sub-service.
Query Parameters
| Parameter | Type | Required | Description |
| brand_id | integer | Optional | Filter by brand ID |
| sub_service_id | integer | Optional | Filter by sub-service ID |
Response
200 OK
{
"success": true,
"data": [
{
"id": 1,
"name": "Redmi Note 13 Pro",
"slug": "redmi-note-13-pro",
"product_codes": ["garnet"],
"brand": {
"id": 1,
"name": "Xiaomi",
"slug": "xiaomi"
}
}
]
}
Search devices by name or product code. Minimum 2 characters required.
Query Parameters
| Parameter | Type | Required | Description |
| q | string | Required | Search query (minimum 2 characters) |
Response
200 OK
{
"success": true,
"data": [
{
"id": 1,
"name": "Redmi Note 13 Pro",
"slug": "redmi-note-13-pro",
"product_codes": ["garnet"],
"brand": {
"id": 1,
"name": "Xiaomi",
"slug": "xiaomi"
}
}
]
}
💲 Pricing
Get pricing for a specific sub-service. Optionally filter by device to get device-specific pricing.
URL Parameters
| Parameter | Type | Required | Description |
| subServiceSlug | string | Required | Sub-service slug (e.g., standard-cpid) |
Query Parameters
| Parameter | Type | Required | Description |
| device_id | integer | Optional | Device ID for device-specific pricing |
Response
200 OK
{
"success": true,
"data": {
"sub_service": "standard-cpid",
"sell_price": 2.50,
"currency": "USD"
}
}
🚀 Service Execute
Execute a service operation. Deducts balance from the user and processes the requested service. Balance is refunded on failure.
Request Headers
| Header | Value |
| Authorization | Bearer {token} |
| Content-Type | application/json |
| Accept | application/json |
Request Body
| Parameter | Type | Required | Description |
| service_slug | string | Required | Service slug (e.g., cpid) |
| sub_service_slug | string | Required | Sub-service slug (e.g., standard-cpid) |
| device_id | integer | Optional | Target device ID |
| input_data | object | Required | Service-specific input data |
| input_data.product_code | string | Required | Device product code |
| input_data.cpu_id | string | Required | Hardware identifier (CPU ID) |
| input_data.imei1 | string | Required | IMEI slot 1 (15 digits) |
| input_data.imei2 | string | Optional | IMEI slot 2 (15 digits) |
Response Examples
200 OK
{
"success": true,
"data": {
"record_id": 156,
"message": "Service executed successfully.",
"data": {
"product_code": "garnet",
"cpu_id": "A1B2C3D4E5F6",
"download_url": "/api/v1/records/156/download"
}
}
}
402 Insufficient Balance
{
"success": false,
"message": "Insufficient balance. Please top up your account."
}
404 Not Found
{
"success": false,
"message": "Service executor not found for this service."
}
422 Validation Error
{
"success": false,
"message": "Validation failed.",
"errors": {
"service_slug": ["The service slug field is required."],
"input_data.product_code": ["The product code field is required."]
}
}
502 Execution Failed
{
"success": false,
"message": "Service execution failed. Your balance has been refunded."
}
🌐 DHRU Fusion API
This API provides reseller integration compatible with DHRU Fusion panels (GSMFusion, DhruFusion, etc.).
It allows you to check account info, list available services, place orders, and query order status.
Endpoint
POST
https://xiaomitoolkit.com/dhru_api.php
Authentication
All requests require the apiaccesskey parameter in the POST body.
Generate your API key from Profile > API Settings in the panel.
Returns your account information including credit balance, email, and currency.
Request Parameters
| Parameter | Type | Required | Description |
| action | string | Required | Must be accountinfo |
| apiaccesskey | string | Required | Your API key |
Request
action=accountinfo&apiaccesskey=YOUR_API_KEY
Success Response
{
"SUCCESS": [
{
"MESSAGE": "Your Account Info",
"AccountInfo": {
"credit": 150.50,
"mail": "[email protected]",
"currency": "USD"
}
}
]
}
Returns the list of available IMEI services with their IDs, names, and pricing.
Request Parameters
| Parameter | Type | Required | Description |
| action | string | Required | Must be imeiservicelist |
| apiaccesskey | string | Required | Your API key |
Request
action=imeiservicelist&apiaccesskey=YOUR_API_KEY
Success Response
{
"SUCCESS": [
{
"MESSAGE": "IMEI Service List",
"LIST": {
"1": {
"SERVICE_NAME": "CPID Generation - Standard",
"GROUP_NAME": "CPID Services",
"CREDIT": "2.50"
},
"2": {
"SERVICE_NAME": "CPID Generation - Premium",
"GROUP_NAME": "CPID Services",
"CREDIT": "5.00"
}
}
}
]
}
Places a new IMEI service order. The parameters field must be a Base64-encoded JSON string.
Request Parameters
| Parameter | Type | Required | Description |
| action | string | Required | Must be placeimeiorder |
| apiaccesskey | string | Required | Your API key |
| parameters | string | Required | Base64-encoded JSON (see below) |
Parameters JSON Fields (before Base64 encoding)
| Field | Type | Required | Description |
| ID | integer | Required | Sub-service ID (from imeiservicelist) |
| product_code | string | Required | Device product code (e.g. begonia) |
| cpu_id | string | Required | CPU ID / HWID of the device |
| IMEI | string | Required | IMEI 1 of the device |
| IMEI2 | string | Optional | IMEI 2 of the device |
Request Example
action=placeimeiorder&apiaccesskey=YOUR_API_KEY¶meters=BASE64_ENCODED_JSON
# JSON before encoding:
{
"ID": 1,
"product_code": "begonia",
"cpu_id": "0xABC123DEF456",
"IMEI": "861234567890123",
"IMEI2": "861234567890124"
}
Success Response
{
"SUCCESS": [
{
"MESSAGE": "Order Confirmed",
"REFERENCEID": "42"
}
]
}
Error Response
{
"ERROR": [
{
"MESSAGE": "Insufficient credit."
}
]
}
Query the status of a previously placed order using its reference ID.
Request Parameters
| Parameter | Type | Required | Description |
| action | string | Required | Must be getimeiorder |
| apiaccesskey | string | Required | Your API key |
| parameters | string | Required | XML string: <PARAMETERS><ID>ORDER_ID</ID></PARAMETERS> |
Request Example
action=getimeiorder&apiaccesskey=YOUR_API_KEY¶meters=<PARAMETERS><ID>42</ID></PARAMETERS>
Success Response (Completed)
{
"SUCCESS": [
{
"STATUS": "4",
"CODE": "Available"
}
]
}
Status Codes
| Status | Meaning | Description |
| 1 | Pending | Order is being processed |
| 3 | Failed / Denied | Order failed or was denied |
| 4 | Completed | Order completed successfully, result in CODE field |
🔧 DHRU Panel Integration
Follow these steps to connect your DHRU Fusion panel to XiaomiToolkit as a supplier.
Setup Steps
- In your DHRU panel, navigate to Supplier > Add Supplier
- Set API URL to:
https://xiaomitoolkit.com/dhru_api.php
- Set API Key to the key generated from Profile > API Settings
- Click Test Connection — the service list will be fetched automatically
- Map supplier services to your panel services and start accepting orders
API Key Management
Your API key can be generated, regenerated, or removed from the
API Settings page in your account profile.
Only users with
dealer,
reseller, or
admin roles can access API features.