KDEFY SMS API
API REST para comprar números virtuales y recibir SMS. Usa el mismo saldo y las mismas activaciones de tu cuenta en el sitio.
https://kdefy-sms.com/api/v1X-API-KeyTodas las rutas
| GET | /balance | Saldo y totales de la cuenta. |
| GET | /profile | Usuario, saldo y fecha de creación. |
| GET | /countries | Lista de países. |
| GET | /services | Servicios de un país, con stock y precio inicial. |
| GET | /operators | Operadoras de un país. |
| GET | /offers | Franjas de precio y stock de un servicio en un país. |
| GET POST | /number/get | Compra un número, o varios con quantity. |
| GET | /number/status | Estado de la activación y códigos recibidos. |
| GET POST | /number/cancel | Cancela y devuelve el valor. |
| GET POST | /number/finish | Cierra la activación después del código. |
| GET | /activations | Tus activaciones, incluidas las del sitio, de la más nueva a la más antigua. |
| GET | /transactions | Recargas, compras y reembolsos. |
Integrar con IA
Pega el texto de abajo en ChatGPT, Claude o Gemini y di qué quieres construir. El prompt ya incluye las rutas, reglas y errores de la 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
Consola de pruebas
Generar o ver mi token →Estos valores valen para todas las pruebas de la página. El token solo se queda en esta pestaña. Comprar descuenta saldo de verdad.
Autenticación
Genera el token en API, en el menú del sitio, y envíalo en el header X-API-Key en cada solicitud. Authorization: Bearer y ?api_key= también funcionan, pero la query string acaba en logs de proxy y en el historial del navegador. Generar otro token invalida el anterior al instante. No uses el token en el 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"
Respuestas e idioma
- Toda respuesta es JSON. Éxito: { "status": "success", ... }. Error: { "status": "error", "error": "codigo", "message": "texto" }.
- Decide según el campo error. Es estable. message es texto para personas y puede cambiar.
- message y state_label siguen el idioma de la cuenta (pt o en). Para forzarlo: ?lang=pt o ?lang=en.
- Las claves del JSON y los valores de state no cambian con el idioma.
- Valores en BRL con punto decimal. Fechas en ISO 8601 (UTC).
Estados
| state | Significado |
|---|---|
waiting | Esperando el primer código. |
code_received | Código recibido. Los códigos nuevos entran en codes mientras la activación esté abierta. |
completed | Finalizada por ti (/number/finish). |
cancelled | Cancelada. Valor devuelto. |
expired | Sin código en 20 min. Valor devuelto automáticamente. |
Límites
- 120 solicitudes por minuto por cuenta.
- Compra: hasta 50 números por solicitud y 50 por minuto. Por encima: limite_de_numeros.
- Status: consulta cada 5 s. Más rápido no adelanta el código.
Flujo de compra
- GET /services?country=73: servicios del país y precio inicial.
- GET /offers?country=73&service=wa (opcional): franjas de precio y stock.
- GET /number/get?country=73&service=wa&request_id=...: compra y devuelve phone e id.
- GET /number/status?id=ID cada 5 s, hasta que code llegue relleno.
- Con código: GET /number/finish?id=ID. Sin código: GET /number/cancel?id=ID (se habilita 2 min después de la compra) y el valor vuelve al saldo.
Esperando el código
Consulta /number/status cada 5 s y detente cuando code venga relleno o state pase a cancelled, expired o completed.
- Define un plazo máximo en tu código (20 min).
- Con varios números, usa /activations?state=active. Una llamada trae todas las activas.
- Una activación puede recibir más de un código. Lee codes[].
Compra en lote
quantity=N compra N números en una llamada, hasta 50. La compra parcial es normal: si el stock o el saldo se acaba a mitad, el resto no se cobra.
- La respuesta trae numbers[], requested, purchased y failed.
- errors lista el motivo de los fallos, si los hay.
- Límite de 50 números por minuto por cuenta.
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"
Idempotencia (request_id)
Envía request_id en cada compra. Si hay timeout y no sabes si la compra salió, repite la misma llamada con la misma request_id. La API devuelve la respuesta original, con el header Idempotent-Replay: true, y no cobra de nuevo.
- Compra nueva, request_id nueva.
- 8 a 80 caracteres (letras, números, _ . : -). El header Idempotency-Key también vale.
- La clave dura 24 h y solo se guarda cuando la compra salió bien. Una compra fallida se puede repetir.
- Misma clave con parámetros distintos: request_id_reutilizada.
Ejemplo completo
Compra, espera el código y finaliza. Si el código no llega, cancela. La compra usa request_id, así que repetir la llamada no la duplica.
// 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."
fiBuenas prácticas
- Token en variable de entorno. Nunca en el código, el front-end o un repositorio.
- request_id en cada compra. ¿Repetiste la llamada? Misma request_id.
- Polling de 5 s, con plazo máximo.
- Varios números: /activations?state=active en lugar de un /number/status por activación.
- Trata error, no message.
- 429: espera retry_in_seconds. 502: reintenta con espera creciente (2 s, 4 s, 6 s).
- Usa max_price_brl como tope. Precio y stock cambian, así que consulta /offers antes de lotes grandes.
- Revisa /balance antes de lotes grandes.
- Guarda request_id e id de la activación en los logs.
- Cancela solo lo que no vayas a usar. Después del primer código no hay reembolso.
Cuenta
/api/v1/balance
Saldo
Saldo y totales de la cuenta.
Campos de la respuesta
| Campo | Tipo | Descripción |
|---|---|---|
balance_brl | number | Saldo disponible. |
total_spent_brl | number | Total gastado en la cuenta. |
total_recharged_brl | number | Total recargado. |
currency | string | Siempre "BRL". |
Ejemplo
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 .Respuesta
{
"status": "success",
"balance_brl": 25.4,
"total_spent_brl": 12.1,
"total_recharged_brl": 37.5,
"currency": "BRL"
}
Probar
/api/v1/profile
Perfil
Usuario, saldo y fecha de creación.
Campos de la respuesta
| Campo | Tipo | Descripción |
|---|---|---|
username | string | Usuario. |
balance_brl | number | Saldo disponible. |
created_at | string | Creación de la cuenta (ISO 8601). |
Ejemplo
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 .Respuesta
{
"status": "success",
"username": "maria",
"balance_brl": 25.4,
"created_at": "2026-09-01T12:00:00.000Z"
}
Probar
Catálogo
/api/v1/countries
Países
Lista de países. Usa el id en country.
Campos de la respuesta
| Campo | Tipo | Descripción |
|---|---|---|
countries[].id | integer | ID del país. Úsalo en country. |
countries[].name | string | Nombre. |
countries[].dial_code | string | null | Prefijo, p. ej.: +55. |
Ejemplo
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 .Respuesta
{
"status": "success",
"countries": [
{
"id": 73,
"name": "Brasil",
"dial_code": "+55"
}
]
}
Probar
/api/v1/services
Servicios
Servicios de un país, con stock y precio inicial. Usa code en service.
Parámetros
| Nombre | Descripción | |
|---|---|---|
country | obligatorio | ID del país. |
Campos de la respuesta
| Campo | Tipo | Descripción |
|---|---|---|
country | integer | País consultado. |
services[].code | string | Código. Úsalo en service. |
services[].name | string | Nombre. |
services[].available | integer | Stock. |
services[].from_price_brl | number | null | Precio de la oferta más barata. |
Errores
Ejemplo
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 .Respuesta
{
"status": "success",
"country": 73,
"services": [
{
"code": "wa",
"name": "WhatsApp",
"available": 1240,
"from_price_brl": 7.1
}
]
}
Probar
/api/v1/operators
Operadoras
Operadoras de un país. Uso opcional en operator al comprar.
Parámetros
| Nombre | Descripción | |
|---|---|---|
country | obligatorio | ID del país. |
Campos de la respuesta
| Campo | Tipo | Descripción |
|---|---|---|
country | integer | País consultado. |
operators[].id | string | ID de la operadora. Úsalo en operator. |
operators[].name | string | Nombre. |
Errores
Ejemplo
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 .Respuesta
{
"status": "success",
"country": 73,
"operators": [
{
"id": "vivo",
"name": "vivo"
}
]
}
Probar
/api/v1/offers
Ofertas
Franjas de precio y stock de un servicio en un país. Las baratas tienen poco stock; las más caras suelen tener número.
Parámetros
| Nombre | Descripción | |
|---|---|---|
country | obligatorio | ID del país. |
service | obligatorio | Código del servicio. |
Campos de la respuesta
| Campo | Tipo | Descripción |
|---|---|---|
offers[].price_brl | number | Precio de la franja. |
offers[].available | integer | Stock de la franja. |
Errores
Ejemplo
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 .Respuesta
{
"status": "success",
"country": 73,
"service": "wa",
"offers": [
{
"price_brl": 7.1,
"available": 12
},
{
"price_brl": 8.4,
"available": 340
}
]
}
Probar
Números
/api/v1/number/get
Comprar número
Compra un número, o varios con quantity. Se debita al instante. Si el número se cancela o expira sin código, el valor vuelve al saldo.
Parámetros
| Nombre | Descripción | |
|---|---|---|
country | obligatorio | ID del país. |
service | obligatorio | Código del servicio. |
max_price_brl | opcional | Tope de precio. Usa la franja más cara que quepa. Sin esto, usa la más barata. |
operator | opcional | Operadora. Por defecto: cualquiera. Restringe el stock. |
quantity | opcional | Cantidad, de 1 a 50. Sin esto compra 1 y la respuesta viene en formato simple. |
request_id | opcional | Clave anti-duplicación, 8 a 80 caracteres. El header Idempotency-Key también vale. Recomendada. |
Campos de la respuesta
| Campo | Tipo | Descripción |
|---|---|---|
id | string | ID de la activación. Va en /number/status, /number/cancel y /number/finish. |
service | string | Código del servicio. |
service_name | string | Nombre del servicio. Viene del proveedor, no se traduce. |
country | integer | ID del país. |
country_name | string | Nombre del país. |
phone | string | Número con prefijo, solo dígitos (5511999999999). |
state | string | Estado de la activación (mira Estados). Valor fijo en inglés; usa este en la lógica. |
state_label | string | Estado en texto, en el idioma de la cuenta. Solo para mostrar. |
code | string | null | Último código recibido. null mientras no llegue. |
codes | array | Todos los códigos, [{ code, received_at }], del más antiguo al más nuevo. |
price_brl | number | Valor cobrado, en reales. |
seconds_left | integer | Segundos hasta que la activación expire. |
cancel_in_seconds | integer | Segundos hasta habilitar la cancelación. 0 = ya se puede. |
balance_brl | number | Saldo después de la compra. |
| con quantity | ||
requested | integer | Cantidad pedida. |
purchased | integer | Cantidad comprada. |
failed | integer | Cantidad no comprada (no se cobra). |
numbers | array | Activaciones, con los mismos campos de arriba. |
errors | array | Códigos de error de las compras que fallaron (compra parcial). |
Errores
Ejemplo
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 .Respuesta
{
"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
}
Respuesta con 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
}
Probar
/api/v1/number/status
Estado y código
Estado de la activación y códigos recibidos.
Parámetros
| Nombre | Descripción | |
|---|---|---|
id | obligatorio | ID de la activación, viene de la compra. |
Campos de la respuesta
| Campo | Tipo | Descripción |
|---|---|---|
id | string | ID de la activación. Va en /number/status, /number/cancel y /number/finish. |
service | string | Código del servicio. |
service_name | string | Nombre del servicio. Viene del proveedor, no se traduce. |
country | integer | ID del país. |
country_name | string | Nombre del país. |
phone | string | Número con prefijo, solo dígitos (5511999999999). |
state | string | Estado de la activación (mira Estados). Valor fijo en inglés; usa este en la lógica. |
state_label | string | Estado en texto, en el idioma de la cuenta. Solo para mostrar. |
code | string | null | Último código recibido. null mientras no llegue. |
codes | array | Todos los códigos, [{ code, received_at }], del más antiguo al más nuevo. |
price_brl | number | Valor cobrado, en reales. |
seconds_left | integer | Segundos hasta que la activación expire. |
cancel_in_seconds | integer | Segundos hasta habilitar la cancelación. 0 = ya se puede. |
Errores
Ejemplo
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 .Respuesta
{
"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
}
Probar
/api/v1/number/cancel
Cancelar
Cancela y devuelve el valor. Solo sin código y 2 min después de la compra; antes responde cancelamento_muito_cedo con retry_in_seconds. En la API no hay multa por cancelaciones seguidas.
Parámetros
| Nombre | Descripción | |
|---|---|---|
id | obligatorio | ID de la activación. |
Campos de la respuesta
| Campo | Tipo | Descripción |
|---|---|---|
id | string | ID de la activación. |
state | string | Siempre "cancelled". |
refunded_brl | number | Valor devuelto. |
balance_brl | number | Saldo después del reembolso. |
Errores
Ejemplo
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 .Respuesta
{
"status": "success",
"id": "1842",
"state": "cancelled",
"refunded_brl": 8.4,
"balance_brl": 25.4
}
Probar
/api/v1/number/finish
Finalizar
Cierra la activación después del código. Deja de esperar códigos extra. Sin reembolso.
Parámetros
| Nombre | Descripción | |
|---|---|---|
id | obligatorio | ID de la activación. |
Campos de la respuesta
| Campo | Tipo | Descripción |
|---|---|---|
id | string | ID de la activación. |
state | string | Siempre "completed". |
Errores
Ejemplo
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 .Respuesta
{
"status": "success",
"id": "1842",
"state": "completed"
}
Probar
Historial
/api/v1/activations
Listar activaciones
Tus activaciones, incluidas las del sitio, de la más nueva a la más antigua.
Parámetros
| Nombre | Descripción | |
|---|---|---|
state | opcional | "active" lista solo las que están en curso. |
limit | opcional | Máximo de elementos. Por defecto 50, máx. 100. |
Campos de la respuesta
| Campo | Tipo | Descripción |
|---|---|---|
activations[] | array | Activaciones, con los mismos campos de /number/status. |
Ejemplo
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 .Respuesta
{
"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
}
]
}
Probar
/api/v1/transactions
Extracto
Recargas, compras y reembolsos.
Parámetros
| Nombre | Descripción | |
|---|---|---|
limit | opcional | Máximo de elementos. Por defecto 50, máx. 200. |
Campos de la respuesta
| Campo | Tipo | Descripción |
|---|---|---|
transactions[].type | string | Tipo (PURCHASE, REFUND...). |
transactions[].amount_brl | number | Valor. |
transactions[].balance_after_brl | number | Saldo después. |
transactions[].description | string | Descripción. |
transactions[].created_at | string | Fecha (ISO 8601). |
Ejemplo
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 .Respuesta
{
"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"
}
]
}
Probar
Errores
Formato: { "status": "error", "error": "saldo_insuficiente", "message": "..." }. Decide según el campo error.
| HTTP | error | Cuándo | Qué hacer |
|---|---|---|---|
| 401 | token_nao_informado token_invalido | Token ausente, inválido o revocado. | Corrige el token. No repitas. |
| 403 | conta_bloqueada token_suspenso | Cuenta bloqueada o API suspendida por el admin. | Habla con soporte. |
| 400 | pais_invalido servico_invalido id_invalido quantidade_invalida preco_invalido operador_invalido request_id_invalido | Parámetro ausente o inválido. | Corrige la llamada. |
| 402 | saldo_insuficiente | Saldo menor que el precio. | Recarga en el sitio. |
| 404 | sem_numeros_disponiveis oferta_indisponivel | Sin stock en esta franja ahora. | Sube max_price_brl, cambia el país o inténtalo después. |
| 404 | ativacao_nao_encontrada | ID inexistente o de otra cuenta. | Revisa el id. |
| 409 | requisicao_em_andamento | La request_id aún se está procesando. | Espera y repite la misma llamada. |
| 409 | cancelamento_muito_cedo | Menos de 2 min desde la compra. | Espera retry_in_seconds. |
| 409 | ativacao_nao_cancelavel ativacao_nao_finalizavel | El estado actual no permite la acción. | Consulta /number/status. |
| 422 | request_id_reutilizada | Misma request_id con parámetros distintos. | Usa una request_id nueva. |
| 422 | preco_abaixo_do_minimo | max_price_brl menor que la oferta más barata. | Súbelo a min_price_brl o más. |
| 429 | limite_de_requisicoes limite_de_numeros | Se superó el límite. | Espera retry_in_seconds. |
| 502 | falha_temporaria | Inestabilidad. No se te cobra. | Repite con espera creciente, misma request_id. |
Preguntas frecuentes
¿Cuánto tarda el código?
En general segundos, pero depende del servicio. La activación espera hasta 20 min. Sin código en ese plazo, expira y el valor vuelve al saldo.
Tuve timeout en la compra. ¿Y ahora?
Repite la misma llamada con la misma request_id: vuelve la respuesta original y no se cobra de nuevo. Si no usaste request_id, lista /activations?state=active antes de comprar otra vez.
¿Puedo cancelar justo después de comprar?
No. La cancelación se habilita 2 min después de la compra. cancel_in_seconds muestra cuánto falta.
sem_numeros_disponiveis con saldo. ¿Por qué?
La franja de precio no tiene stock ahora. Sube max_price_brl, cambia el país o mira dónde hay stock en /offers.
¿El precio cambia entre la consulta y la compra?
Puede cambiar. Vale el price_brl de la respuesta de la compra, y max_price_brl impide que pase de tu tope.
¿Necesito request_id?
No es obligatoria, pero úsala en cualquier automatización. Sin ella, repetir la llamada por error compra dos veces.
¿Se pueden comprar más de 50 números?
No en una solicitud, y el tope es 50 por minuto por cuenta. Por encima la API responde limite_de_numeros.
¿Por qué la respuesta viene en portugués?
message y state_label siguen el idioma de la cuenta. Fuérzalo con ?lang=pt o ?lang=en. Las claves del JSON, state y los códigos de error son siempre los mismos.
¿Cómo recargo el saldo?
En el sitio, con PIX. El saldo de la API es el mismo del sitio.
El token se filtró.
Genera otro en API, en el sitio. El anterior deja de funcionar al instante. Si viste un uso extraño, habla con soporte.
Reglas de uso
- Cada activación espera el código hasta 20 min. Sin código, expira y el valor vuelve al saldo.
- Después del primer código no hay reembolso.
- Solo ves y operas tus propias activaciones.
- La recarga de saldo se hace en el sitio (PIX).
- Toda solicitud queda registrada en la cuenta. El admin consulta el uso del token.
- El abuso o el fraude pueden bloquear la cuenta.