Receive your credential
Your administrator creates a client-specific credential. The complete secret is displayed only once.
Integrate FRP and FDL authorization into your application with client-specific credentials, server-side billing, strict validation and idempotent request recovery.
A production operation requires one API credential, one unique operation key and one valid service payload.
Your administrator creates a client-specific credential. The complete secret is displayed only once.
Send validate_only: true to verify access and configuration without contacting the provider or charging credit.
Remove validate_only, use a new idempotency key and keep that same key for every retry of the operation.
Credentials belong in the Authorization header. Usernames and panel passwords are never accepted by API V1.
https://clickfrptool.com/login/api/v1/sell.phpAuthorization: Bearer cft_live_PUBLIC_ID.SECRET Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000 Content-Type: application/json Accept: application/json
Idempotency identifies one logical device operation and protects it from accidental duplicate requests.
Generate a unique key containing 16–80 safe characters. A UUID is recommended. Never reuse it for another payload.
Resend the identical JSON with the exact same key. Do not generate another key for the same device operation.
provider_status_unknown, do not submit a new operation. Contact support and provide only the returned request_id.Both services use the same endpoint but require different Base64 source data.
The value is Base64 containing the complete FRP JSON expected by the device workflow.
{
"service": "frp",
"configblob": "BASE64_OF_FRP_JSON"
}The value is Base64 of only the raw Fastboot token. Do not wrap the token in JSON before encoding it.
{
"service": "fdl",
"configblob": "BASE64_OF_RAW_FASTBOOT_TOKEN"
}This checks the credential, IP policy, permission, payload, pricing, balance, provider configuration and protected recovery storage. It does not contact the provider and charges 0.00.
{
"service": "fdl",
"configblob": "BASE64_OF_RAW_FASTBOOT_TOKEN",
"validate_only": true
}Replace placeholders locally. Never hardcode production credentials in a distributable desktop executable.
curl --request POST "https://clickfrptool.com/login/api/v1/sell.php" \
--header "Authorization: Bearer YOUR_API_CREDENTIAL" \
--header "Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data '{"service":"fdl","configblob":"BASE64_OF_RAW_FASTBOOT_TOKEN"}'<?php
$endpoint = 'https://clickfrptool.com/login/api/v1/sell.php';
$credential = getenv('CLICK_FRP_API_CREDENTIAL');
$idempotencyKey = bin2hex(random_bytes(16));
$payload = json_encode([
'service' => 'fdl',
'configblob' => base64_encode($rawFastbootToken),
], JSON_UNESCAPED_SLASHES);
$curl = curl_init($endpoint);
curl_setopt_array($curl, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 15,
CURLOPT_TIMEOUT => 150,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $credential,
'Idempotency-Key: ' . $idempotencyKey,
'Content-Type: application/json',
'Accept: application/json',
],
CURLOPT_POSTFIELDS => $payload,
]);
$response = curl_exec($curl);
$httpCode = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode((string) $response, true);using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
public static async Task<string> RequestFdlAsync(
string credential, string rawFastbootToken, string operationKey)
{
using (var client = new HttpClient { Timeout = TimeSpan.FromSeconds(150) })
using (var request = new HttpRequestMessage(HttpMethod.Post,
"https://clickfrptool.com/login/api/v1/sell.php"))
{
request.Headers.Authorization =
new AuthenticationHeaderValue("Bearer", credential);
request.Headers.Add("Idempotency-Key", operationKey);
request.Headers.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
string configblob = Convert.ToBase64String(
Encoding.UTF8.GetBytes(rawFastbootToken));
string json = "{\"service\":\"fdl\",\"configblob\":\"" +
configblob + "\"}";
request.Content = new StringContent(json, Encoding.UTF8, "application/json");
using (HttpResponseMessage response = await client.SendAsync(request))
return await response.Content.ReadAsStringAsync();
}
}import base64
import os
import uuid
import requests
endpoint = "https://clickfrptool.com/login/api/v1/sell.php"
credential = os.environ["CLICK_FRP_API_CREDENTIAL"]
operation_key = str(uuid.uuid4())
configblob = base64.b64encode(raw_fastboot_token.encode()).decode()
response = requests.post(
endpoint,
headers={
"Authorization": f"Bearer {credential}",
"Idempotency-Key": operation_key,
"Accept": "application/json",
},
json={"service": "fdl", "configblob": configblob},
timeout=(15, 150),
)
result = response.json()The HTTP status and the JSON success value must both be evaluated.
{
"success": true,
"request_id": "32_HEX_CHARACTERS",
"error": null,
"message": "Authorization generated successfully",
"timestamp": "2026-09-04T12:00:00Z",
"data": {
"operation_id": "32_HEX_CHARACTERS",
"service": "fdl",
"response": "AUTHORIZATION_TOKEN",
"billing": {
"amount_charged": "1.00",
"balance": "394.00",
"reused": false
}
}
}{
"success": false,
"request_id": "32_HEX_CHARACTERS",
"error": {
"code": "insufficient_credit",
"message": "Not enough credit"
},
"message": "Not enough credit",
"timestamp": "2026-09-04T12:00:00Z",
"data": {
"balance": "0.50",
"price": "1.00"
}
}data.response, success path success, expected value true.Use the machine-readable error.code value. Do not parse the human-readable message.
| HTTP | Error code | Meaning | Required action |
|---|---|---|---|
| 400 | invalid_idempotency_key | Operation key is missing or malformed. | Create a valid 16–80 character key before the first attempt. |
| 401 | invalid_api_key | Credential is invalid, incomplete or rotated. | Stop and request a credential rotation. |
| 402 | insufficient_credit | The account balance is lower than the service price. | Add credit and retry with the same operation data. |
| 403 | account_disabled | The API client or user account is disabled. | Contact the account administrator. |
| 403 | ip_not_allowed | The request source is outside the configured allowlist. | Add the correct fixed public IP. |
| 403 | service_not_allowed | FRP or FDL is not enabled for this client. | Request service permission. |
| 409 | request_in_progress | The same operation is currently processing. | Wait briefly, then resend identical JSON with the same key. |
| 409 | idempotency_conflict | The key was reused with different data. | Do not retry until the integration bug is corrected. |
| 422 | invalid_configblob | The Base64 payload does not match the service contract. | Correct the payload before retrying. |
| 422 | provider_rejected | The provider rejected the operation. | No Click credit was charged. Verify device data. |
| 429 | rate_limit_exceeded | The client exceeded its per-minute request limit. | Wait for the Retry-After value. |
| 502 | upstream_unavailable | The provider failed before returning valid authorization. | No Click credit was charged. Retry according to support guidance. |
| 503 | recovery_pending | Authorization is protected and settlement is pending. | Retry identical JSON with the same key. |
| 503 | provider_status_unknown | The upstream result is ambiguous. | Do not create another operation. Contact support with request_id. |
| 503 | maintenance | The B2B gateway is temporarily disabled. | Wait and retry later. |
Integrations are safest when secrets stay server-side and operational data is deliberately minimized.
Store credentials in an environment variable or protected server configuration. Rotate immediately after suspected exposure.
Never log the Authorization header, configblob, raw device token or returned authorization response.
Check both the HTTP status and JSON success value. Keep the request ID for safe support investigation.