KDEFY SMS API
API REST pour acheter des numéros virtuels et recevoir des SMS. Elle utilise le même solde et les mêmes activations que votre compte sur le site.
https://kdefy-sms.com/api/v1X-API-KeyToutes les routes
| GET | /balance | Solde et totaux du compte. |
| GET | /profile | Utilisateur, solde et date de création. |
| GET | /countries | Liste des pays. |
| GET | /services | Services d’un pays, avec stock et prix de départ. |
| GET | /operators | Opérateurs d’un pays. |
| GET | /offers | Paliers de prix et stock d’un service dans un pays. |
| GET POST | /number/get | Achète un numéro, ou plusieurs avec quantity. |
| GET | /number/status | État de l’activation et codes reçus. |
| GET POST | /number/cancel | Annule et rembourse le montant. |
| GET POST | /number/finish | Clôture l’activation après le code. |
| GET | /activations | Vos activations, y compris celles du site, de la plus récente à la plus ancienne. |
| GET | /transactions | Recharges, achats et remboursements. |
Intégrer avec l’IA
Collez le texte ci-dessous dans ChatGPT, Claude ou Gemini et dites ce que vous voulez construire. Le prompt contient déjà les routes, règles et erreurs de l’API.
# TAREFA
Escreva o código de integração com a KDEFY SMS API: compra de números virtuais e leitura de SMS.
Use só o que está neste documento. Se faltar informação, pergunte. Não invente rota, campo ou código de erro.
# ANTES DE CODAR
Faça as perguntas abaixo numa única mensagem e espere a resposta. Pule o que eu já tiver dito.
1. Linguagem e framework (com versão).
2. O que o código faz (cadastro automático, revenda, painel...).
3. Onde roda e onde fica o token.
4. Volume esperado (números por minuto) e se precisa de compra em lote.
# COMO RESPONDER
1. Plano em até 3 linhas.
2. Código completo e executável.
3. Como rodar e testar.
4. Limites e riscos que o código trata.
# API
Base URL: https://kdefy-sms.com/api/v1
Auth: header X-API-Key: <TOKEN> em toda requisição. O token vem de variável de ambiente (KDEFY_API_KEY). Nunca no front-end, nunca em log.
Métodos: tudo é GET. /number/get, /number/cancel e /number/finish também aceitam POST.
Resposta: JSON. Sucesso { "status": "success", ... }. Erro { "status": "error", "error": "codigo", "message": "texto" }.
Decida sempre por "error". "message" muda com o idioma.
Limites: 120 requisições por minuto por conta. Compra: até 50 números por requisição e 50 por minuto. Acima disso: limite_de_numeros.
# ROTAS (* = obrigatório)
GET /balance
Saldo e totais da conta.
params: nenhum
retorna: balance_brl, total_spent_brl, total_recharged_brl, currency
GET /profile
Usuário, saldo e data de criação.
params: nenhum
retorna: username, balance_brl, created_at
GET /countries
Lista de países.
params: nenhum
retorna: countries[].id, countries[].name, countries[].dial_code
GET /services
Serviços de um país, com estoque e preço inicial.
params: country*
retorna: country, services[].code, services[].name, services[].available, services[].from_price_brl
erros: pais_invalido
GET /operators
Operadoras de um país.
params: country*
retorna: country, operators[].id, operators[].name
erros: pais_invalido
GET /offers
Faixas de preço e estoque de um serviço num país.
params: country*, service*
retorna: offers[].price_brl, offers[].available
erros: pais_invalido, servico_invalido, sem_numeros_disponiveis
GET|POST /number/get
Compra um número, ou vários com quantity.
params: country*, service*, max_price_brl, operator, quantity, request_id
retorna: id, service, service_name, country, country_name, phone, state, state_label, code, codes, price_brl, seconds_left, cancel_in_seconds, balance_brl, requested, purchased, failed, numbers, errors
erros: pais_invalido, servico_invalido, quantidade_invalida, preco_invalido, operador_invalido, request_id_invalido, request_id_reutilizada, requisicao_em_andamento, saldo_insuficiente, sem_numeros_disponiveis, preco_abaixo_do_minimo, limite_de_numeros, falha_temporaria
GET /number/status
Estado da ativação e códigos recebidos.
params: id*
retorna: id, service, service_name, country, country_name, phone, state, state_label, code, codes, price_brl, seconds_left, cancel_in_seconds
erros: id_invalido, ativacao_nao_encontrada
GET|POST /number/cancel
Cancela e devolve o valor.
params: id*
retorna: id, state, refunded_brl, balance_brl
erros: id_invalido, ativacao_nao_encontrada, ativacao_nao_cancelavel, cancelamento_muito_cedo, falha_temporaria
GET|POST /number/finish
Encerra a ativação depois do código.
params: id*
retorna: id, state
erros: id_invalido, ativacao_nao_encontrada, ativacao_nao_finalizavel
GET /activations
Suas ativações, inclusive as do site, da mais nova para a mais antiga.
params: state, limit
retorna: activations[]
GET /transactions
Recargas, compras e reembolsos.
params: limit
retorna: transactions[].type, transactions[].amount_brl, transactions[].balance_after_brl, transactions[].description, transactions[].created_at
Exemplo, /number/get:
{
"id": "1842",
"service": "wa",
"service_name": "WhatsApp",
"country": 73,
"country_name": "Brasil",
"phone": "5511999999999",
"state": "waiting",
"state_label": "Aguardando código",
"code": null,
"codes": [],
"price_brl": 8.4,
"seconds_left": 1200,
"cancel_in_seconds": 120,
"status": "success",
"balance_brl": 17
}
Exemplo, /number/status com código:
{
"status": "success",
"id": "1842",
"service": "wa",
"service_name": "WhatsApp",
"country": 73,
"country_name": "Brasil",
"phone": "5511999999999",
"state": "code_received",
"state_label": "Código recebido",
"code": "123456",
"codes": [
{
"code": "123456",
"received_at": "2026-10-19T14:02:11.000Z"
}
],
"price_brl": 8.4,
"seconds_left": 1103,
"cancel_in_seconds": 0
}
# ESTADOS (campo state)
waiting: Esperando o primeiro código.
code_received: Código recebido. Códigos novos entram em codes enquanto a ativação estiver aberta.
completed: Finalizada por você (/number/finish).
cancelled: Cancelada. Valor devolvido.
expired: Sem código em 20 min. Valor devolvido automaticamente.
waiting → code_received → completed
waiting → cancelled (cancel, só sem código e após 2 min)
waiting → expired (automático, com reembolso)
# ERROS E O QUE FAZER
401 token_nao_informado / token_invalido
→ Corrija o token. Não repita.
403 conta_bloqueada / token_suspenso
→ Fale com o suporte.
400 pais_invalido / servico_invalido / id_invalido / quantidade_invalida / preco_invalido / operador_invalido / request_id_invalido
→ Corrija a chamada.
402 saldo_insuficiente
→ Recarregue no site.
404 sem_numeros_disponiveis / oferta_indisponivel
→ Suba max_price_brl, troque o país ou tente depois.
404 ativacao_nao_encontrada
→ Confira o id.
409 requisicao_em_andamento
→ Espere e repita a mesma chamada.
409 cancelamento_muito_cedo
→ Espere retry_in_seconds.
409 ativacao_nao_cancelavel / ativacao_nao_finalizavel
→ Consulte /number/status.
422 request_id_reutilizada
→ Use uma request_id nova.
422 preco_abaixo_do_minimo
→ Suba para min_price_brl ou mais.
429 limite_de_requisicoes / limite_de_numeros
→ Espere retry_in_seconds.
502 falha_temporaria
→ Repita com espera crescente, mesma request_id.
# REGRAS DO CÓDIGO
1. Compra nova = request_id nova (UUID). Repetição da mesma compra = mesma request_id. Nunca gere request_id nova para repetir.
2. Repita a compra só em timeout, erro de rede, 502 ou requisicao_em_andamento. Máximo 4 tentativas, esperando 2 s, 4 s, 6 s.
3. saldo_insuficiente e sem_numeros_disponiveis não se repetem. Devolva o erro a quem chamou.
4. Espere o código com /number/status a cada 5 s, com prazo máximo de 20 min. Pare em code preenchido ou state cancelled, expired ou completed.
5. Vários números ao mesmo tempo: uma chamada a /activations?state=active por ciclo, não uma por número.
6. Com código usado: /number/finish. Sem código e desistindo: /number/cancel. Se vier cancelamento_muito_cedo, espere retry_in_seconds e tente de novo. Se vier ativacao_nao_cancelavel, já chegou código: consulte /number/status.
7. Lote (quantity): leia purchased e failed. Compra parcial é normal.
8. 429: espere retry_in_seconds.
9. Timeout de rede de 20 s por chamada.
10. Log com request_id e id da ativação. Nunca com o token.
# EXEMPLO DE REFERÊNCIA (JavaScript)
```js
// Node 18+. Rode com: KDEFY_API_KEY=seu_token node kdefy.mjs
import { randomUUID } from "node:crypto";
const BASE = "https://kdefy-sms.com/api/v1";
const KEY = process.env.KDEFY_API_KEY;
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
async function api(path, params = {}) {
const qs = new URLSearchParams(params).toString();
const res = await fetch(`${BASE}${path}${qs ? "?" + qs : ""}`, {
headers: { "X-API-Key": KEY },
signal: AbortSignal.timeout(20000),
});
const body = await res.json();
if (body.status !== "success") {
const err = new Error(body.message);
err.code = body.error;
err.http = res.status;
err.retryIn = body.retry_in_seconds;
throw err;
}
return body;
}
async function buy(country, service) {
const requestId = randomUUID(); // uma por compra
for (let attempt = 1; attempt <= 4; attempt++) {
try {
return await api("/number/get", { country, service, request_id: requestId });
} catch (e) {
const transient = e.name === "TimeoutError" || e.name === "TypeError" || e.http === 502 || e.code === "requisicao_em_andamento";
if (!transient || attempt === 4) throw e;
await sleep(2000 * attempt); // repete com a mesma request_id
}
}
}
async function waitForCode(id, maxMinutes = 20) {
const deadline = Date.now() + maxMinutes * 60_000;
while (Date.now() < deadline) {
const s = await api("/number/status", { id });
if (s.code || ["cancelled", "expired", "completed"].includes(s.state)) return s;
await sleep(5000);
}
return null;
}
const number = await buy(73, "wa");
console.log("Número:", number.phone);
const result = await waitForCode(number.id);
if (result?.code) {
console.log("Código:", result.code);
await api("/number/finish", { id: number.id });
} else {
try {
await api("/number/cancel", { id: number.id });
} catch (e) {
if (e.code !== "cancelamento_muito_cedo") throw e;
await sleep((e.retryIn + 1) * 1000);
await api("/number/cancel", { id: number.id });
}
console.log("Cancelado e reembolsado.");
}
```
# CHECKLIST ANTES DE ENTREGAR
- Token só de variável de ambiente.
- Toda compra tem request_id, e a repetição reaproveita a mesma.
- Polling de 5 s com prazo máximo.
- Decisões por "error", nunca por "message".
- Cancelamento trata cancelamento_muito_cedo.
- Testes ou passos de teste para: compra ok, repetição com a mesma request_id, saldo_insuficiente, cancelar antes de 2 min.
# MAIS DETALHES
Docs completas em texto: https://kdefy-sms.com/api/v1/docs.txt
Docs completas em JSON: https://kdefy-sms.com/api/v1/docs.json
OpenAPI 3: https://kdefy-sms.com/api/v1/openapi.json
Console de test
Générer ou voir mon token →Ces valeurs valent pour tous les tests de la page. Le token reste uniquement dans cet onglet. Acheter débite réellement votre solde.
Authentification
Générez le jeton dans API, dans le menu du site, et envoyez-le dans l’en-tête X-API-Key à chaque requête. Authorization: Bearer et ?api_key= fonctionnent aussi, mais la query string finit dans les logs de proxy et l’historique du navigateur. Générer un nouveau jeton invalide immédiatement le précédent. N’utilisez pas le jeton côté front-end.
curl "https://kdefy-sms.com/api/v1/balance" -H "X-API-Key: SEU_TOKEN"curl "https://kdefy-sms.com/api/v1/balance" -H "Authorization: Bearer SEU_TOKEN"curl "https://kdefy-sms.com/api/v1/balance?api_key=SEU_TOKEN"
Réponses et langue
- Toute réponse est en JSON. Succès : { "status": "success", ... }. Erreur : { "status": "error", "error": "code", "message": "texte" }.
- Décidez à partir du champ error. Il est stable. message est un texte pour humains et peut changer.
- message et state_label suivent la langue du compte (pt ou en). Pour la forcer : ?lang=pt ou ?lang=en.
- Les clés JSON et les valeurs de state ne changent pas avec la langue.
- Montants en BRL avec point décimal. Dates en ISO 8601 (UTC).
États
| state | Signification |
|---|---|
waiting | En attente du premier code. |
code_received | Code reçu. Les nouveaux codes s’ajoutent à codes tant que l’activation est ouverte. |
completed | Terminée par vous (/number/finish). |
cancelled | Annulée. Montant remboursé. |
expired | Aucun code en 20 min. Montant remboursé automatiquement. |
Limites
- 120 requêtes par minute par compte.
- Achat : jusqu’à 50 numéros par requête et 50 par minute. Au-delà : limite_de_numeros.
- Statut : interrogez toutes les 5 s. Plus vite n’accélère pas l’arrivée du code.
Parcours d’achat
- GET /services?country=73 : services du pays et prix de départ.
- GET /offers?country=73&service=wa (facultatif) : paliers de prix et stock.
- GET /number/get?country=73&service=wa&request_id=... : achète et renvoie phone et id.
- GET /number/status?id=ID toutes les 5 s, jusqu’à ce que code soit rempli.
- Avec code : GET /number/finish?id=ID. Sans code : GET /number/cancel?id=ID (possible 2 min après l’achat) et le montant revient au solde.
Attendre le code
Interrogez /number/status toutes les 5 s et arrêtez quand code est rempli ou que state passe à cancelled, expired ou completed.
- Définissez un délai maximal dans votre code (20 min).
- Avec plusieurs numéros, utilisez /activations?state=active. Un seul appel renvoie toutes les actives.
- Une activation peut recevoir plus d’un code. Lisez codes[].
Achat en lot
quantity=N achète N numéros en un appel, jusqu’à 50. Un achat partiel est normal : si le stock ou le solde manque en cours de route, le reste n’est pas débité.
- La réponse contient numbers[], requested, purchased et failed.
- errors liste le motif des échecs, le cas échéant.
- Limite de 50 numéros par minute par compte.
curl "https://kdefy-sms.com/api/v1/number/get?country=73&service=wa&quantity=3&request_id=pedido-0001" \
-H "X-API-Key: $KDEFY_API_KEY"
Idempotence (request_id)
Envoyez request_id à chaque achat. En cas de timeout, si vous ne savez pas si l’achat a abouti, répétez le même appel avec la même request_id. L’API renvoie la réponse d’origine, avec l’en-tête Idempotent-Replay: true, et ne débite pas à nouveau.
- Nouvel achat, nouvelle request_id.
- 8 à 80 caractères (lettres, chiffres, _ . : -). L’en-tête Idempotency-Key fonctionne aussi.
- La clé dure 24 h et n’est enregistrée que si l’achat a réussi. Un achat échoué peut être répété.
- Même clé avec des paramètres différents : request_id_reutilizada.
Exemple complet
Achetez, attendez le code et terminez. Si le code n’arrive pas, annulez. L’achat utilise request_id, donc répéter l’appel ne le duplique pas.
// Node 18+. Rode com: KDEFY_API_KEY=seu_token node kdefy.mjs
import { randomUUID } from "node:crypto";
const BASE = "https://kdefy-sms.com/api/v1";
const KEY = process.env.KDEFY_API_KEY;
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
async function api(path, params = {}) {
const qs = new URLSearchParams(params).toString();
const res = await fetch(`${BASE}${path}${qs ? "?" + qs : ""}`, {
headers: { "X-API-Key": KEY },
signal: AbortSignal.timeout(20000),
});
const body = await res.json();
if (body.status !== "success") {
const err = new Error(body.message);
err.code = body.error;
err.http = res.status;
err.retryIn = body.retry_in_seconds;
throw err;
}
return body;
}
async function buy(country, service) {
const requestId = randomUUID(); // uma por compra
for (let attempt = 1; attempt <= 4; attempt++) {
try {
return await api("/number/get", { country, service, request_id: requestId });
} catch (e) {
const transient = e.name === "TimeoutError" || e.name === "TypeError" || e.http === 502 || e.code === "requisicao_em_andamento";
if (!transient || attempt === 4) throw e;
await sleep(2000 * attempt); // repete com a mesma request_id
}
}
}
async function waitForCode(id, maxMinutes = 20) {
const deadline = Date.now() + maxMinutes * 60_000;
while (Date.now() < deadline) {
const s = await api("/number/status", { id });
if (s.code || ["cancelled", "expired", "completed"].includes(s.state)) return s;
await sleep(5000);
}
return null;
}
const number = await buy(73, "wa");
console.log("Número:", number.phone);
const result = await waitForCode(number.id);
if (result?.code) {
console.log("Código:", result.code);
await api("/number/finish", { id: number.id });
} else {
try {
await api("/number/cancel", { id: number.id });
} catch (e) {
if (e.code !== "cancelamento_muito_cedo") throw e;
await sleep((e.retryIn + 1) * 1000);
await api("/number/cancel", { id: number.id });
}
console.log("Cancelado e reembolsado.");
}# Python 3.9+. pip install requests
# Rode com: KDEFY_API_KEY=seu_token python kdefy.py
import os, time, uuid, requests
BASE = "https://kdefy-sms.com/api/v1"
HEADERS = {"X-API-Key": os.environ["KDEFY_API_KEY"]}
class ApiError(Exception):
def __init__(self, body, http):
super().__init__(body.get("message"))
self.code = body.get("error")
self.http = http
self.retry_in = body.get("retry_in_seconds")
def api(path, **params):
r = requests.get(BASE + path, params=params, headers=HEADERS, timeout=20)
body = r.json()
if body.get("status") != "success":
raise ApiError(body, r.status_code)
return body
def buy(country, service):
request_id = str(uuid.uuid4()) # uma por compra
for attempt in range(1, 5):
try:
return api("/number/get", country=country, service=service, request_id=request_id)
except requests.RequestException:
pass
except ApiError as e:
if not (e.http == 502 or e.code == "requisicao_em_andamento"):
raise
if attempt == 4:
raise RuntimeError("não foi possível comprar agora")
time.sleep(2 * attempt) # repete com a mesma request_id
def wait_for_code(activation_id, max_minutes=20):
deadline = time.time() + max_minutes * 60
while time.time() < deadline:
s = api("/number/status", id=activation_id)
if s["code"] or s["state"] in ("cancelled", "expired", "completed"):
return s
time.sleep(5)
return None
number = buy(73, "wa")
print("Número:", number["phone"])
result = wait_for_code(number["id"])
if result and result["code"]:
print("Código:", result["code"])
api("/number/finish", id=number["id"])
else:
try:
api("/number/cancel", id=number["id"])
except ApiError as e:
if e.code != "cancelamento_muito_cedo":
raise
time.sleep((e.retry_in or 5) + 1)
api("/number/cancel", id=number["id"])
print("Cancelado e reembolsado.")<?php
// PHP 8+ com ext-curl. Rode com: KDEFY_API_KEY=seu_token php kdefy.php
const BASE = "https://kdefy-sms.com/api/v1";
function api(string $path, array $params = []): array {
$ch = curl_init(BASE . $path . ($params ? "?" . http_build_query($params) : ""));
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 20,
CURLOPT_HTTPHEADER => ["X-API-Key: " . getenv("KDEFY_API_KEY")],
]);
$raw = curl_exec($ch);
if ($raw === false) throw new RuntimeException("rede: " . curl_error($ch));
$body = json_decode($raw, true);
if (($body["status"] ?? null) !== "success") {
$e = new RuntimeException($body["error"] ?? "erro_desconhecido");
$e->retryIn = $body["retry_in_seconds"] ?? 0;
throw $e;
}
return $body;
}
$requestId = bin2hex(random_bytes(16)); // uma por compra
$n = api("/number/get", ["country" => 73, "service" => "wa", "request_id" => $requestId]);
echo "Número: {$n['phone']}\n";
$deadline = time() + 20 * 60;
while (time() < $deadline) {
$s = api("/number/status", ["id" => $n["id"]]);
if (!empty($s["code"]) || in_array($s["state"], ["cancelled", "expired", "completed"], true)) break;
sleep(5);
}
if (!empty($s["code"])) {
echo "Código: {$s['code']}\n";
api("/number/finish", ["id" => $n["id"]]);
} else {
api("/number/cancel", ["id" => $n["id"]]);
echo "Cancelado e reembolsado.\n";
}# Ruby 3+. Rode com: KDEFY_API_KEY=seu_token ruby kdefy.rb
require "net/http"
require "json"
require "securerandom"
BASE = "https://kdefy-sms.com/api/v1"
def api(path, params = {})
uri = URI(BASE + path)
uri.query = URI.encode_www_form(params) unless params.empty?
req = Net::HTTP::Get.new(uri, "X-API-Key" => ENV.fetch("KDEFY_API_KEY"))
res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https", read_timeout: 20) { |h| h.request(req) }
body = JSON.parse(res.body)
raise "#{body['error']}: #{body['message']}" unless body["status"] == "success"
body
end
n = api("/number/get", country: 73, service: "wa", request_id: SecureRandom.uuid) # uma por compra
puts "Número: #{n['phone']}"
deadline = Time.now + 20 * 60
s = nil
while Time.now < deadline
s = api("/number/status", id: n["id"])
break if s["code"] || %w[cancelled expired completed].include?(s["state"])
sleep 5
end
if s && s["code"]
puts "Código: #{s['code']}"
api("/number/finish", id: n["id"])
else
api("/number/cancel", id: n["id"])
puts "Cancelado e reembolsado."
end#!/usr/bin/env bash
# Requer curl e jq. Rode com: KDEFY_API_KEY=seu_token bash kdefy.sh
set -euo pipefail
BASE="https://kdefy-sms.com/api/v1"
api() { # api /rota chave=valor ...
local path="$1"; shift
local args=(); for kv in "$@"; do args+=(--data-urlencode "$kv"); done
curl -sS --max-time 20 -G "$BASE$path" -H "X-API-Key: $KDEFY_API_KEY" "${args[@]}"
}
num=$(api /number/get country=73 service=wa "request_id=$(uuidgen)") # uma por compra
[ "$(jq -r .status <<<"$num")" = success ] || { jq . <<<"$num"; exit 1; }
id=$(jq -r .id <<<"$num")
echo "Número: $(jq -r .phone <<<"$num")"
for _ in $(seq 240); do # 240 x 5 s = 20 min
st=$(api /number/status "id=$id")
code=$(jq -r '.code // empty' <<<"$st")
state=$(jq -r .state <<<"$st")
[ -n "$code" ] && break
case "$state" in cancelled|expired|completed) break ;; esac
sleep 5
done
if [ -n "${code:-}" ]; then
echo "Código: $code"
api /number/finish "id=$id" >/dev/null
else
api /number/cancel "id=$id" >/dev/null
echo "Cancelado e reembolsado."
fiBonnes pratiques
- Jeton dans une variable d’environnement. Jamais dans le code, le front-end ou un dépôt.
- request_id à chaque achat. Appel répété ? Même request_id.
- Polling de 5 s, avec délai maximal.
- Plusieurs numéros : /activations?state=active au lieu d’un /number/status par activation.
- Traitez error, pas message.
- 429 : attendez retry_in_seconds. 502 : réessayez avec une attente croissante (2 s, 4 s, 6 s).
- Utilisez max_price_brl comme plafond. Prix et stock changent, consultez donc /offers avant les gros lots.
- Vérifiez /balance avant les gros lots.
- Conservez request_id et l’id de l’activation dans vos logs.
- N’annulez que ce que vous n’utiliserez pas. Après le premier code, pas de remboursement.
Compte
/api/v1/balance
Solde
Solde et totaux du compte.
Champs de la réponse
| Champ | Type | Description |
|---|---|---|
balance_brl | number | Solde disponible. |
total_spent_brl | number | Total dépensé sur le compte. |
total_recharged_brl | number | Total rechargé. |
currency | string | Toujours "BRL". |
Exemple
curl "https://kdefy-sms.com/api/v1/balance" \
-H "X-API-Key: $KDEFY_API_KEY"const res = await fetch("https://kdefy-sms.com/api/v1/balance", {
headers: { "X-API-Key": process.env.KDEFY_API_KEY },
});
const data = await res.json();
if (data.status !== "success") throw new Error(data.error);
console.log(data);import os, requests
r = requests.get(
"https://kdefy-sms.com/api/v1/balance",
headers={"X-API-Key": os.environ["KDEFY_API_KEY"]},
timeout=20,
)
data = r.json()
if data["status"] != "success":
raise RuntimeError(data["error"])
print(data)<?php
$ch = curl_init("https://kdefy-sms.com/api/v1/balance");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 20,
CURLOPT_HTTPHEADER => ["X-API-Key: " . getenv("KDEFY_API_KEY")],
]);
$data = json_decode(curl_exec($ch), true);
if (($data["status"] ?? null) !== "success") {
throw new RuntimeException($data["error"] ?? "erro_desconhecido");
}
print_r($data);require "net/http"
require "json"
uri = URI("https://kdefy-sms.com/api/v1/balance")
req = Net::HTTP::Get.new(uri, "X-API-Key" => ENV.fetch("KDEFY_API_KEY"))
res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https", read_timeout: 20) { |http| http.request(req) }
data = JSON.parse(res.body)
abort(data["error"]) unless data["status"] == "success"
puts JSON.pretty_generate(data)#!/usr/bin/env bash
curl -sS --max-time 20 -G "https://kdefy-sms.com/api/v1/balance" \
-H "X-API-Key: $KDEFY_API_KEY" | jq .Réponse
{
"status": "success",
"balance_brl": 25.4,
"total_spent_brl": 12.1,
"total_recharged_brl": 37.5,
"currency": "BRL"
}
Tester
/api/v1/profile
Profil
Utilisateur, solde et date de création.
Champs de la réponse
| Champ | Type | Description |
|---|---|---|
username | string | Utilisateur. |
balance_brl | number | Solde disponible. |
created_at | string | Création du compte (ISO 8601). |
Exemple
curl "https://kdefy-sms.com/api/v1/profile" \
-H "X-API-Key: $KDEFY_API_KEY"const res = await fetch("https://kdefy-sms.com/api/v1/profile", {
headers: { "X-API-Key": process.env.KDEFY_API_KEY },
});
const data = await res.json();
if (data.status !== "success") throw new Error(data.error);
console.log(data);import os, requests
r = requests.get(
"https://kdefy-sms.com/api/v1/profile",
headers={"X-API-Key": os.environ["KDEFY_API_KEY"]},
timeout=20,
)
data = r.json()
if data["status"] != "success":
raise RuntimeError(data["error"])
print(data)<?php
$ch = curl_init("https://kdefy-sms.com/api/v1/profile");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 20,
CURLOPT_HTTPHEADER => ["X-API-Key: " . getenv("KDEFY_API_KEY")],
]);
$data = json_decode(curl_exec($ch), true);
if (($data["status"] ?? null) !== "success") {
throw new RuntimeException($data["error"] ?? "erro_desconhecido");
}
print_r($data);require "net/http"
require "json"
uri = URI("https://kdefy-sms.com/api/v1/profile")
req = Net::HTTP::Get.new(uri, "X-API-Key" => ENV.fetch("KDEFY_API_KEY"))
res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https", read_timeout: 20) { |http| http.request(req) }
data = JSON.parse(res.body)
abort(data["error"]) unless data["status"] == "success"
puts JSON.pretty_generate(data)#!/usr/bin/env bash
curl -sS --max-time 20 -G "https://kdefy-sms.com/api/v1/profile" \
-H "X-API-Key: $KDEFY_API_KEY" | jq .Réponse
{
"status": "success",
"username": "maria",
"balance_brl": 25.4,
"created_at": "2026-09-01T12:00:00.000Z"
}
Tester
Catalogue
/api/v1/countries
Pays
Liste des pays. Utilisez l’id dans country.
Champs de la réponse
| Champ | Type | Description |
|---|---|---|
countries[].id | integer | ID du pays. À utiliser dans country. |
countries[].name | string | Nom. |
countries[].dial_code | string | null | Indicatif, ex. : +55. |
Exemple
curl "https://kdefy-sms.com/api/v1/countries" \
-H "X-API-Key: $KDEFY_API_KEY"const res = await fetch("https://kdefy-sms.com/api/v1/countries", {
headers: { "X-API-Key": process.env.KDEFY_API_KEY },
});
const data = await res.json();
if (data.status !== "success") throw new Error(data.error);
console.log(data);import os, requests
r = requests.get(
"https://kdefy-sms.com/api/v1/countries",
headers={"X-API-Key": os.environ["KDEFY_API_KEY"]},
timeout=20,
)
data = r.json()
if data["status"] != "success":
raise RuntimeError(data["error"])
print(data)<?php
$ch = curl_init("https://kdefy-sms.com/api/v1/countries");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 20,
CURLOPT_HTTPHEADER => ["X-API-Key: " . getenv("KDEFY_API_KEY")],
]);
$data = json_decode(curl_exec($ch), true);
if (($data["status"] ?? null) !== "success") {
throw new RuntimeException($data["error"] ?? "erro_desconhecido");
}
print_r($data);require "net/http"
require "json"
uri = URI("https://kdefy-sms.com/api/v1/countries")
req = Net::HTTP::Get.new(uri, "X-API-Key" => ENV.fetch("KDEFY_API_KEY"))
res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https", read_timeout: 20) { |http| http.request(req) }
data = JSON.parse(res.body)
abort(data["error"]) unless data["status"] == "success"
puts JSON.pretty_generate(data)#!/usr/bin/env bash
curl -sS --max-time 20 -G "https://kdefy-sms.com/api/v1/countries" \
-H "X-API-Key: $KDEFY_API_KEY" | jq .Réponse
{
"status": "success",
"countries": [
{
"id": 73,
"name": "Brasil",
"dial_code": "+55"
}
]
}
Tester
/api/v1/services
Services
Services d’un pays, avec stock et prix de départ. Utilisez code dans service.
Paramètres
| Nom | Description | |
|---|---|---|
country | obligatoire | ID du pays. |
Champs de la réponse
| Champ | Type | Description |
|---|---|---|
country | integer | Pays interrogé. |
services[].code | string | Code. À utiliser dans service. |
services[].name | string | Nom. |
services[].available | integer | Stock. |
services[].from_price_brl | number | null | Prix de l’offre la moins chère. |
Erreurs
Exemple
curl "https://kdefy-sms.com/api/v1/services?country=73" \
-H "X-API-Key: $KDEFY_API_KEY"const res = await fetch("https://kdefy-sms.com/api/v1/services?country=73", {
headers: { "X-API-Key": process.env.KDEFY_API_KEY },
});
const data = await res.json();
if (data.status !== "success") throw new Error(data.error);
console.log(data);import os, requests
r = requests.get(
"https://kdefy-sms.com/api/v1/services",
params={"country": 73},
headers={"X-API-Key": os.environ["KDEFY_API_KEY"]},
timeout=20,
)
data = r.json()
if data["status"] != "success":
raise RuntimeError(data["error"])
print(data)<?php
$ch = curl_init("https://kdefy-sms.com/api/v1/services?country=73");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 20,
CURLOPT_HTTPHEADER => ["X-API-Key: " . getenv("KDEFY_API_KEY")],
]);
$data = json_decode(curl_exec($ch), true);
if (($data["status"] ?? null) !== "success") {
throw new RuntimeException($data["error"] ?? "erro_desconhecido");
}
print_r($data);require "net/http"
require "json"
uri = URI("https://kdefy-sms.com/api/v1/services?country=73")
req = Net::HTTP::Get.new(uri, "X-API-Key" => ENV.fetch("KDEFY_API_KEY"))
res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https", read_timeout: 20) { |http| http.request(req) }
data = JSON.parse(res.body)
abort(data["error"]) unless data["status"] == "success"
puts JSON.pretty_generate(data)#!/usr/bin/env bash
curl -sS --max-time 20 -G "https://kdefy-sms.com/api/v1/services" \
-H "X-API-Key: $KDEFY_API_KEY" \
--data-urlencode "country=73" | jq .Réponse
{
"status": "success",
"country": 73,
"services": [
{
"code": "wa",
"name": "WhatsApp",
"available": 1240,
"from_price_brl": 7.1
}
]
}
Tester
/api/v1/operators
Opérateurs
Opérateurs d’un pays. Usage facultatif dans operator à l’achat.
Paramètres
| Nom | Description | |
|---|---|---|
country | obligatoire | ID du pays. |
Champs de la réponse
| Champ | Type | Description |
|---|---|---|
country | integer | Pays interrogé. |
operators[].id | string | ID de l’opérateur. À utiliser dans operator. |
operators[].name | string | Nom. |
Erreurs
Exemple
curl "https://kdefy-sms.com/api/v1/operators?country=73" \
-H "X-API-Key: $KDEFY_API_KEY"const res = await fetch("https://kdefy-sms.com/api/v1/operators?country=73", {
headers: { "X-API-Key": process.env.KDEFY_API_KEY },
});
const data = await res.json();
if (data.status !== "success") throw new Error(data.error);
console.log(data);import os, requests
r = requests.get(
"https://kdefy-sms.com/api/v1/operators",
params={"country": 73},
headers={"X-API-Key": os.environ["KDEFY_API_KEY"]},
timeout=20,
)
data = r.json()
if data["status"] != "success":
raise RuntimeError(data["error"])
print(data)<?php
$ch = curl_init("https://kdefy-sms.com/api/v1/operators?country=73");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 20,
CURLOPT_HTTPHEADER => ["X-API-Key: " . getenv("KDEFY_API_KEY")],
]);
$data = json_decode(curl_exec($ch), true);
if (($data["status"] ?? null) !== "success") {
throw new RuntimeException($data["error"] ?? "erro_desconhecido");
}
print_r($data);require "net/http"
require "json"
uri = URI("https://kdefy-sms.com/api/v1/operators?country=73")
req = Net::HTTP::Get.new(uri, "X-API-Key" => ENV.fetch("KDEFY_API_KEY"))
res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https", read_timeout: 20) { |http| http.request(req) }
data = JSON.parse(res.body)
abort(data["error"]) unless data["status"] == "success"
puts JSON.pretty_generate(data)#!/usr/bin/env bash
curl -sS --max-time 20 -G "https://kdefy-sms.com/api/v1/operators" \
-H "X-API-Key: $KDEFY_API_KEY" \
--data-urlencode "country=73" | jq .Réponse
{
"status": "success",
"country": 73,
"operators": [
{
"id": "vivo",
"name": "vivo"
}
]
}
Tester
/api/v1/offers
Offres
Paliers de prix et stock d’un service dans un pays. Les paliers bon marché ont peu de stock ; les plus chers ont en général des numéros.
Paramètres
| Nom | Description | |
|---|---|---|
country | obligatoire | ID du pays. |
service | obligatoire | Code du service. |
Champs de la réponse
| Champ | Type | Description |
|---|---|---|
offers[].price_brl | number | Prix du palier. |
offers[].available | integer | Stock du palier. |
Erreurs
Exemple
curl "https://kdefy-sms.com/api/v1/offers?country=73&service=wa" \
-H "X-API-Key: $KDEFY_API_KEY"const res = await fetch("https://kdefy-sms.com/api/v1/offers?country=73&service=wa", {
headers: { "X-API-Key": process.env.KDEFY_API_KEY },
});
const data = await res.json();
if (data.status !== "success") throw new Error(data.error);
console.log(data);import os, requests
r = requests.get(
"https://kdefy-sms.com/api/v1/offers",
params={"country": 73, "service": "wa"},
headers={"X-API-Key": os.environ["KDEFY_API_KEY"]},
timeout=20,
)
data = r.json()
if data["status"] != "success":
raise RuntimeError(data["error"])
print(data)<?php
$ch = curl_init("https://kdefy-sms.com/api/v1/offers?country=73&service=wa");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 20,
CURLOPT_HTTPHEADER => ["X-API-Key: " . getenv("KDEFY_API_KEY")],
]);
$data = json_decode(curl_exec($ch), true);
if (($data["status"] ?? null) !== "success") {
throw new RuntimeException($data["error"] ?? "erro_desconhecido");
}
print_r($data);require "net/http"
require "json"
uri = URI("https://kdefy-sms.com/api/v1/offers?country=73&service=wa")
req = Net::HTTP::Get.new(uri, "X-API-Key" => ENV.fetch("KDEFY_API_KEY"))
res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https", read_timeout: 20) { |http| http.request(req) }
data = JSON.parse(res.body)
abort(data["error"]) unless data["status"] == "success"
puts JSON.pretty_generate(data)#!/usr/bin/env bash
curl -sS --max-time 20 -G "https://kdefy-sms.com/api/v1/offers" \
-H "X-API-Key: $KDEFY_API_KEY" \
--data-urlencode "country=73" \
--data-urlencode "service=wa" | jq .Réponse
{
"status": "success",
"country": 73,
"service": "wa",
"offers": [
{
"price_brl": 7.1,
"available": 12
},
{
"price_brl": 8.4,
"available": 340
}
]
}
Tester
Numéros
/api/v1/number/get
Acheter un numéro
Achète un numéro, ou plusieurs avec quantity. Débité immédiatement. Si le numéro est annulé ou expire sans code, le montant revient au solde.
Paramètres
| Nom | Description | |
|---|---|---|
country | obligatoire | ID du pays. |
service | obligatoire | Code du service. |
max_price_brl | optionnel | Plafond de prix. Utilise le palier le plus cher qui y rentre. Sans cela, le moins cher. |
operator | optionnel | Opérateur. Par défaut : n’importe lequel. Restreint le stock. |
quantity | optionnel | Quantité, de 1 à 50. Sans cela, achète 1 et la réponse arrive au format simple. |
request_id | optionnel | Clé anti-doublon, 8 à 80 caractères. L’en-tête Idempotency-Key fonctionne aussi. Recommandée. |
Champs de la réponse
| Champ | Type | Description |
|---|---|---|
id | string | ID de l’activation. Utilisé dans /number/status, /number/cancel et /number/finish. |
service | string | Code du service. |
service_name | string | Nom du service. Fourni par le prestataire, non traduit. |
country | integer | ID du pays. |
country_name | string | Nom du pays. |
phone | string | Numéro avec indicatif, chiffres uniquement (5511999999999). |
state | string | État de l’activation (voir États). Valeur fixe en anglais ; utilisez-la dans votre logique. |
state_label | string | État en texte, dans la langue du compte. Pour l’affichage uniquement. |
code | string | null | Dernier code reçu. null tant qu’il n’est pas arrivé. |
codes | array | Tous les codes, [{ code, received_at }], du plus ancien au plus récent. |
price_brl | number | Montant débité, en reais. |
seconds_left | integer | Secondes avant l’expiration de l’activation. |
cancel_in_seconds | integer | Secondes avant de pouvoir annuler. 0 = déjà possible. |
balance_brl | number | Solde après l’achat. |
| avec quantity | ||
requested | integer | Quantité demandée. |
purchased | integer | Quantité achetée. |
failed | integer | Quantité non achetée (non débitée). |
numbers | array | Activations, avec les mêmes champs que ci-dessus. |
errors | array | Codes d’erreur des achats échoués (achat partiel). |
Erreurs
Exemple
curl "https://kdefy-sms.com/api/v1/number/get?country=73&service=wa&request_id=pedido-0001" \
-H "X-API-Key: $KDEFY_API_KEY"const res = await fetch("https://kdefy-sms.com/api/v1/number/get?country=73&service=wa&request_id=pedido-0001", {
headers: { "X-API-Key": process.env.KDEFY_API_KEY },
});
const data = await res.json();
if (data.status !== "success") throw new Error(data.error);
console.log(data);import os, requests
r = requests.get(
"https://kdefy-sms.com/api/v1/number/get",
params={"country": 73, "service": "wa", "request_id": "pedido-0001"},
headers={"X-API-Key": os.environ["KDEFY_API_KEY"]},
timeout=20,
)
data = r.json()
if data["status"] != "success":
raise RuntimeError(data["error"])
print(data)<?php
$ch = curl_init("https://kdefy-sms.com/api/v1/number/get?country=73&service=wa&request_id=pedido-0001");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 20,
CURLOPT_HTTPHEADER => ["X-API-Key: " . getenv("KDEFY_API_KEY")],
]);
$data = json_decode(curl_exec($ch), true);
if (($data["status"] ?? null) !== "success") {
throw new RuntimeException($data["error"] ?? "erro_desconhecido");
}
print_r($data);require "net/http"
require "json"
uri = URI("https://kdefy-sms.com/api/v1/number/get?country=73&service=wa&request_id=pedido-0001")
req = Net::HTTP::Get.new(uri, "X-API-Key" => ENV.fetch("KDEFY_API_KEY"))
res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https", read_timeout: 20) { |http| http.request(req) }
data = JSON.parse(res.body)
abort(data["error"]) unless data["status"] == "success"
puts JSON.pretty_generate(data)#!/usr/bin/env bash
curl -sS --max-time 20 -G "https://kdefy-sms.com/api/v1/number/get" \
-H "X-API-Key: $KDEFY_API_KEY" \
--data-urlencode "country=73" \
--data-urlencode "service=wa" \
--data-urlencode "request_id=pedido-0001" | jq .Réponse
{
"id": "1842",
"service": "wa",
"service_name": "WhatsApp",
"country": 73,
"country_name": "Brasil",
"phone": "5511999999999",
"state": "waiting",
"state_label": "Aguardando código",
"code": null,
"codes": [],
"price_brl": 8.4,
"seconds_left": 1200,
"cancel_in_seconds": 120,
"status": "success",
"balance_brl": 17
}
Réponse avec quantity=2
{
"status": "success",
"requested": 2,
"purchased": 2,
"failed": 0,
"numbers": [
{
"id": "1842",
"service": "wa",
"service_name": "WhatsApp",
"country": 73,
"country_name": "Brasil",
"phone": "5511999999999",
"state": "waiting",
"state_label": "Aguardando código",
"code": null,
"codes": [],
"price_brl": 8.4,
"seconds_left": 1200,
"cancel_in_seconds": 120
},
{
"id": "1843",
"service": "wa",
"service_name": "WhatsApp",
"country": 73,
"country_name": "Brasil",
"phone": "5511988887777",
"state": "waiting",
"state_label": "Aguardando código",
"code": null,
"codes": [],
"price_brl": 8.4,
"seconds_left": 1200,
"cancel_in_seconds": 120
}
],
"balance_brl": 8.6
}
Tester
/api/v1/number/status
Statut et code
État de l’activation et codes reçus.
Paramètres
| Nom | Description | |
|---|---|---|
id | obligatoire | ID de l’activation, issu de l’achat. |
Champs de la réponse
| Champ | Type | Description |
|---|---|---|
id | string | ID de l’activation. Utilisé dans /number/status, /number/cancel et /number/finish. |
service | string | Code du service. |
service_name | string | Nom du service. Fourni par le prestataire, non traduit. |
country | integer | ID du pays. |
country_name | string | Nom du pays. |
phone | string | Numéro avec indicatif, chiffres uniquement (5511999999999). |
state | string | État de l’activation (voir États). Valeur fixe en anglais ; utilisez-la dans votre logique. |
state_label | string | État en texte, dans la langue du compte. Pour l’affichage uniquement. |
code | string | null | Dernier code reçu. null tant qu’il n’est pas arrivé. |
codes | array | Tous les codes, [{ code, received_at }], du plus ancien au plus récent. |
price_brl | number | Montant débité, en reais. |
seconds_left | integer | Secondes avant l’expiration de l’activation. |
cancel_in_seconds | integer | Secondes avant de pouvoir annuler. 0 = déjà possible. |
Erreurs
Exemple
curl "https://kdefy-sms.com/api/v1/number/status?id=1842" \
-H "X-API-Key: $KDEFY_API_KEY"const res = await fetch("https://kdefy-sms.com/api/v1/number/status?id=1842", {
headers: { "X-API-Key": process.env.KDEFY_API_KEY },
});
const data = await res.json();
if (data.status !== "success") throw new Error(data.error);
console.log(data);import os, requests
r = requests.get(
"https://kdefy-sms.com/api/v1/number/status",
params={"id": "1842"},
headers={"X-API-Key": os.environ["KDEFY_API_KEY"]},
timeout=20,
)
data = r.json()
if data["status"] != "success":
raise RuntimeError(data["error"])
print(data)<?php
$ch = curl_init("https://kdefy-sms.com/api/v1/number/status?id=1842");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 20,
CURLOPT_HTTPHEADER => ["X-API-Key: " . getenv("KDEFY_API_KEY")],
]);
$data = json_decode(curl_exec($ch), true);
if (($data["status"] ?? null) !== "success") {
throw new RuntimeException($data["error"] ?? "erro_desconhecido");
}
print_r($data);require "net/http"
require "json"
uri = URI("https://kdefy-sms.com/api/v1/number/status?id=1842")
req = Net::HTTP::Get.new(uri, "X-API-Key" => ENV.fetch("KDEFY_API_KEY"))
res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https", read_timeout: 20) { |http| http.request(req) }
data = JSON.parse(res.body)
abort(data["error"]) unless data["status"] == "success"
puts JSON.pretty_generate(data)#!/usr/bin/env bash
curl -sS --max-time 20 -G "https://kdefy-sms.com/api/v1/number/status" \
-H "X-API-Key: $KDEFY_API_KEY" \
--data-urlencode "id=1842" | jq .Réponse
{
"status": "success",
"id": "1842",
"service": "wa",
"service_name": "WhatsApp",
"country": 73,
"country_name": "Brasil",
"phone": "5511999999999",
"state": "code_received",
"state_label": "Código recebido",
"code": "123456",
"codes": [
{
"code": "123456",
"received_at": "2026-10-19T14:02:11.000Z"
}
],
"price_brl": 8.4,
"seconds_left": 1103,
"cancel_in_seconds": 0
}
Tester
/api/v1/number/cancel
Annuler
Annule et rembourse le montant. Uniquement sans code et 2 min après l’achat ; avant, répond cancelamento_muito_cedo avec retry_in_seconds. Dans l’API, il n’y a pas de pénalité pour des annulations successives.
Paramètres
| Nom | Description | |
|---|---|---|
id | obligatoire | ID de l’activation. |
Champs de la réponse
| Champ | Type | Description |
|---|---|---|
id | string | ID de l’activation. |
state | string | Toujours "cancelled". |
refunded_brl | number | Montant remboursé. |
balance_brl | number | Solde après le remboursement. |
Erreurs
Exemple
curl "https://kdefy-sms.com/api/v1/number/cancel?id=1842" \
-H "X-API-Key: $KDEFY_API_KEY"const res = await fetch("https://kdefy-sms.com/api/v1/number/cancel?id=1842", {
headers: { "X-API-Key": process.env.KDEFY_API_KEY },
});
const data = await res.json();
if (data.status !== "success") throw new Error(data.error);
console.log(data);import os, requests
r = requests.get(
"https://kdefy-sms.com/api/v1/number/cancel",
params={"id": "1842"},
headers={"X-API-Key": os.environ["KDEFY_API_KEY"]},
timeout=20,
)
data = r.json()
if data["status"] != "success":
raise RuntimeError(data["error"])
print(data)<?php
$ch = curl_init("https://kdefy-sms.com/api/v1/number/cancel?id=1842");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 20,
CURLOPT_HTTPHEADER => ["X-API-Key: " . getenv("KDEFY_API_KEY")],
]);
$data = json_decode(curl_exec($ch), true);
if (($data["status"] ?? null) !== "success") {
throw new RuntimeException($data["error"] ?? "erro_desconhecido");
}
print_r($data);require "net/http"
require "json"
uri = URI("https://kdefy-sms.com/api/v1/number/cancel?id=1842")
req = Net::HTTP::Get.new(uri, "X-API-Key" => ENV.fetch("KDEFY_API_KEY"))
res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https", read_timeout: 20) { |http| http.request(req) }
data = JSON.parse(res.body)
abort(data["error"]) unless data["status"] == "success"
puts JSON.pretty_generate(data)#!/usr/bin/env bash
curl -sS --max-time 20 -G "https://kdefy-sms.com/api/v1/number/cancel" \
-H "X-API-Key: $KDEFY_API_KEY" \
--data-urlencode "id=1842" | jq .Réponse
{
"status": "success",
"id": "1842",
"state": "cancelled",
"refunded_brl": 8.4,
"balance_brl": 25.4
}
Tester
/api/v1/number/finish
Terminer
Clôture l’activation après le code. Cesse d’attendre des codes supplémentaires. Sans remboursement.
Paramètres
| Nom | Description | |
|---|---|---|
id | obligatoire | ID de l’activation. |
Champs de la réponse
| Champ | Type | Description |
|---|---|---|
id | string | ID de l’activation. |
state | string | Toujours "completed". |
Erreurs
Exemple
curl "https://kdefy-sms.com/api/v1/number/finish?id=1842" \
-H "X-API-Key: $KDEFY_API_KEY"const res = await fetch("https://kdefy-sms.com/api/v1/number/finish?id=1842", {
headers: { "X-API-Key": process.env.KDEFY_API_KEY },
});
const data = await res.json();
if (data.status !== "success") throw new Error(data.error);
console.log(data);import os, requests
r = requests.get(
"https://kdefy-sms.com/api/v1/number/finish",
params={"id": "1842"},
headers={"X-API-Key": os.environ["KDEFY_API_KEY"]},
timeout=20,
)
data = r.json()
if data["status"] != "success":
raise RuntimeError(data["error"])
print(data)<?php
$ch = curl_init("https://kdefy-sms.com/api/v1/number/finish?id=1842");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 20,
CURLOPT_HTTPHEADER => ["X-API-Key: " . getenv("KDEFY_API_KEY")],
]);
$data = json_decode(curl_exec($ch), true);
if (($data["status"] ?? null) !== "success") {
throw new RuntimeException($data["error"] ?? "erro_desconhecido");
}
print_r($data);require "net/http"
require "json"
uri = URI("https://kdefy-sms.com/api/v1/number/finish?id=1842")
req = Net::HTTP::Get.new(uri, "X-API-Key" => ENV.fetch("KDEFY_API_KEY"))
res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https", read_timeout: 20) { |http| http.request(req) }
data = JSON.parse(res.body)
abort(data["error"]) unless data["status"] == "success"
puts JSON.pretty_generate(data)#!/usr/bin/env bash
curl -sS --max-time 20 -G "https://kdefy-sms.com/api/v1/number/finish" \
-H "X-API-Key: $KDEFY_API_KEY" \
--data-urlencode "id=1842" | jq .Réponse
{
"status": "success",
"id": "1842",
"state": "completed"
}
Tester
Historique
/api/v1/activations
Lister les activations
Vos activations, y compris celles du site, de la plus récente à la plus ancienne.
Paramètres
| Nom | Description | |
|---|---|---|
state | optionnel | "active" ne liste que celles en cours. |
limit | optionnel | Nombre maximum d’éléments. Par défaut 50, max 100. |
Champs de la réponse
| Champ | Type | Description |
|---|---|---|
activations[] | array | Activations, avec les mêmes champs que /number/status. |
Exemple
curl "https://kdefy-sms.com/api/v1/activations?state=active" \
-H "X-API-Key: $KDEFY_API_KEY"const res = await fetch("https://kdefy-sms.com/api/v1/activations?state=active", {
headers: { "X-API-Key": process.env.KDEFY_API_KEY },
});
const data = await res.json();
if (data.status !== "success") throw new Error(data.error);
console.log(data);import os, requests
r = requests.get(
"https://kdefy-sms.com/api/v1/activations",
params={"state": "active"},
headers={"X-API-Key": os.environ["KDEFY_API_KEY"]},
timeout=20,
)
data = r.json()
if data["status"] != "success":
raise RuntimeError(data["error"])
print(data)<?php
$ch = curl_init("https://kdefy-sms.com/api/v1/activations?state=active");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 20,
CURLOPT_HTTPHEADER => ["X-API-Key: " . getenv("KDEFY_API_KEY")],
]);
$data = json_decode(curl_exec($ch), true);
if (($data["status"] ?? null) !== "success") {
throw new RuntimeException($data["error"] ?? "erro_desconhecido");
}
print_r($data);require "net/http"
require "json"
uri = URI("https://kdefy-sms.com/api/v1/activations?state=active")
req = Net::HTTP::Get.new(uri, "X-API-Key" => ENV.fetch("KDEFY_API_KEY"))
res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https", read_timeout: 20) { |http| http.request(req) }
data = JSON.parse(res.body)
abort(data["error"]) unless data["status"] == "success"
puts JSON.pretty_generate(data)#!/usr/bin/env bash
curl -sS --max-time 20 -G "https://kdefy-sms.com/api/v1/activations" \
-H "X-API-Key: $KDEFY_API_KEY" \
--data-urlencode "state=active" | jq .Réponse
{
"status": "success",
"activations": [
{
"id": "1842",
"service": "wa",
"service_name": "WhatsApp",
"country": 73,
"country_name": "Brasil",
"phone": "5511999999999",
"state": "waiting",
"state_label": "Aguardando código",
"code": null,
"codes": [],
"price_brl": 8.4,
"seconds_left": 1200,
"cancel_in_seconds": 120
}
]
}
Tester
/api/v1/transactions
Relevé
Recharges, achats et remboursements.
Paramètres
| Nom | Description | |
|---|---|---|
limit | optionnel | Nombre maximum d’éléments. Par défaut 50, max 200. |
Champs de la réponse
| Champ | Type | Description |
|---|---|---|
transactions[].type | string | Type (PURCHASE, REFUND...). |
transactions[].amount_brl | number | Montant. |
transactions[].balance_after_brl | number | Solde après. |
transactions[].description | string | Description. |
transactions[].created_at | string | Date (ISO 8601). |
Exemple
curl "https://kdefy-sms.com/api/v1/transactions?limit=20" \
-H "X-API-Key: $KDEFY_API_KEY"const res = await fetch("https://kdefy-sms.com/api/v1/transactions?limit=20", {
headers: { "X-API-Key": process.env.KDEFY_API_KEY },
});
const data = await res.json();
if (data.status !== "success") throw new Error(data.error);
console.log(data);import os, requests
r = requests.get(
"https://kdefy-sms.com/api/v1/transactions",
params={"limit": 20},
headers={"X-API-Key": os.environ["KDEFY_API_KEY"]},
timeout=20,
)
data = r.json()
if data["status"] != "success":
raise RuntimeError(data["error"])
print(data)<?php
$ch = curl_init("https://kdefy-sms.com/api/v1/transactions?limit=20");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 20,
CURLOPT_HTTPHEADER => ["X-API-Key: " . getenv("KDEFY_API_KEY")],
]);
$data = json_decode(curl_exec($ch), true);
if (($data["status"] ?? null) !== "success") {
throw new RuntimeException($data["error"] ?? "erro_desconhecido");
}
print_r($data);require "net/http"
require "json"
uri = URI("https://kdefy-sms.com/api/v1/transactions?limit=20")
req = Net::HTTP::Get.new(uri, "X-API-Key" => ENV.fetch("KDEFY_API_KEY"))
res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https", read_timeout: 20) { |http| http.request(req) }
data = JSON.parse(res.body)
abort(data["error"]) unless data["status"] == "success"
puts JSON.pretty_generate(data)#!/usr/bin/env bash
curl -sS --max-time 20 -G "https://kdefy-sms.com/api/v1/transactions" \
-H "X-API-Key: $KDEFY_API_KEY" \
--data-urlencode "limit=20" | jq .Réponse
{
"status": "success",
"transactions": [
{
"type": "PURCHASE",
"amount_brl": 8.4,
"balance_after_brl": 17,
"description": "Compra WhatsApp · Brasil (API)",
"created_at": "2026-10-19T14:00:00.000Z"
}
]
}
Tester
Erreurs
Format : { "status": "error", "error": "saldo_insuficiente", "message": "..." }. Décidez à partir du champ error.
| HTTP | error | Quand | Que faire |
|---|---|---|---|
| 401 | token_nao_informado token_invalido | Jeton absent, invalide ou révoqué. | Corrigez le jeton. Ne réessayez pas. |
| 403 | conta_bloqueada token_suspenso | Compte banni ou API suspendue par l’admin. | Contactez le support. |
| 400 | pais_invalido servico_invalido id_invalido quantidade_invalida preco_invalido operador_invalido request_id_invalido | Paramètre manquant ou invalide. | Corrigez l’appel. |
| 402 | saldo_insuficiente | Solde inférieur au prix. | Rechargez sur le site. |
| 404 | sem_numeros_disponiveis oferta_indisponivel | Pas de stock dans ce palier pour le moment. | Augmentez max_price_brl, changez de pays ou réessayez plus tard. |
| 404 | ativacao_nao_encontrada | ID inexistant ou appartenant à un autre compte. | Vérifiez l’id. |
| 409 | requisicao_em_andamento | La request_id est encore en cours de traitement. | Attendez et répétez le même appel. |
| 409 | cancelamento_muito_cedo | Moins de 2 min depuis l’achat. | Attendez retry_in_seconds. |
| 409 | ativacao_nao_cancelavel ativacao_nao_finalizavel | L’état actuel n’autorise pas l’action. | Consultez /number/status. |
| 422 | request_id_reutilizada | Même request_id avec des paramètres différents. | Utilisez une nouvelle request_id. |
| 422 | preco_abaixo_do_minimo | max_price_brl inférieur à l’offre la moins chère. | Montez à min_price_brl ou plus. |
| 429 | limite_de_requisicoes limite_de_numeros | Limite dépassée. | Attendez retry_in_seconds. |
| 502 | falha_temporaria | Instabilité. Vous n’êtes pas débité. | Réessayez avec une attente croissante, même request_id. |
Questions fréquentes
Combien de temps met le code ?
En général quelques secondes, mais cela dépend du service. L’activation attend jusqu’à 20 min. Sans code dans ce délai, elle expire et le montant revient au solde.
Mon achat a expiré (timeout). Et maintenant ?
Répétez le même appel avec la même request_id : la réponse d’origine revient et rien n’est débité à nouveau. Si vous n’avez pas utilisé request_id, listez /activations?state=active avant de racheter.
Puis-je annuler juste après l’achat ?
Non. L’annulation devient possible 2 min après l’achat. cancel_in_seconds indique le temps restant.
sem_numeros_disponiveis avec du solde. Pourquoi ?
Le palier de prix est en rupture pour le moment. Augmentez max_price_brl, changez de pays ou voyez où il y a du stock dans /offers.
Le prix peut-il changer entre la consultation et l’achat ?
Oui. Le price_brl de la réponse d’achat fait foi, et max_price_brl empêche de dépasser votre plafond.
Ai-je besoin de request_id ?
Elle n’est pas obligatoire, mais utilisez-la dans toute automatisation. Sans elle, répéter l’appel par erreur achète deux fois.
Peut-on acheter plus de 50 numéros ?
Pas en une seule requête, et le plafond est de 50 par minute par compte. Au-delà, l’API répond limite_de_numeros.
Pourquoi la réponse est-elle en portugais ?
message et state_label suivent la langue du compte. Forcez-la avec ?lang=pt ou ?lang=en. Les clés JSON, state et les codes d’erreur sont toujours les mêmes.
Comment recharger mon solde ?
Sur le site, via PIX. Le solde de l’API est le même que celui du site.
Mon jeton a fuité.
Générez-en un autre dans API, sur le site. L’ancien cesse de fonctionner immédiatement. Si vous avez vu un usage étrange, contactez le support.
Règles d’utilisation
- Chaque activation attend le code jusqu’à 20 min. Sans code, elle expire et le montant revient au solde.
- Après le premier code, il n’y a pas de remboursement.
- Vous ne voyez et ne gérez que vos propres activations.
- La recharge du solde se fait sur le site (PIX).
- Chaque requête est enregistrée sur le compte. L’admin consulte l’usage du jeton.
- Un abus ou une fraude peut entraîner le blocage du compte.