KDEFY SMS API
TXT JSON Gerar meu tokenToken
v1.0

KDEFY SMS API

API REST para comprar números virtuais e receber SMS. Usa o mesmo saldo e as mesmas ativações da sua conta no site.

Base URL
https://kdefy-sms.com/api/v1
AutenticaçãoX-API-Key
FormatoJSON
Limite120 req/min
Preços da API são menores que os do site
Comprar números pela API custa menos do que comprar pelo site. Se você viu um valor maior no site, é normal: os valores exibidos no site incluem a margem do uso pela interface, e a API cobra uma tarifa reduzida para desenvolvedores. O preço exato de cada compra é sempre o retornado pela rota de ofertas e de serviços.

Todas as rotas

GET /balanceSaldo e totais da conta.
GET /profileUsuário, saldo e data de criação.
GET /countriesLista de países.
GET /servicesServiços de um país, com estoque e preço inicial.
GET /operatorsOperadoras de um país.
GET /countries/topPaíses com estoque para um serviço, na ordem do provedor, com o seu preço inicial.
GET /offersFaixas de preço e estoque de um serviço num país.
GET POST /number/getCompra um número, ou vários com quantity.
GET /number/statusEstado da ativação e códigos recebidos.
GET /number/reactivate/optionsMostra quanto custa reativar o número de uma ativação finalizada que recebeu código.
GET POST /number/reactivateReaproveita o número de uma ativação finalizada para receber um novo código.
GET POST /number/cancelCancela e devolve o valor.
GET POST /number/finishEncerra a ativação depois do código.
GET /activationsSuas ativações, inclusive as do site, da mais nova para a mais antiga.
GET /statsTotal de ativações, taxa de sucesso e gasto por serviço e país num período.
GET /transactionsRecargas, compras e reembolsos.

Estes valores valem para todos os testes da página. O token fica só nesta aba. Comprar debita saldo de verdade.

Começando

Autenticação

Gere o token em API, no menu do site, e mande no header X-API-Key em toda requisição. Authorization: Bearer e ?api_key= também funcionam, mas a query string vai parar em logs de proxy e no histórico do navegador. Gerar outro token invalida o anterior na hora. Não use o token em 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"

Respostas e idioma

  • Toda resposta é JSON. Sucesso: { "status": "success", ... }. Erro: { "status": "error", "error": "codigo", "message": "texto" }.
  • Decida pelo campo error. Ele é estável. message é texto para humano e pode mudar.
  • message e state_label seguem o idioma da conta (pt, en, es, de ou fr). Para forçar: ?lang=pt, ?lang=en, ?lang=es, ?lang=de ou ?lang=fr.
  • As chaves do JSON e os valores de state não mudam com o idioma.
  • Valores em BRL com ponto decimal. Datas em ISO 8601 (UTC).
Conceitos

Estados

stateSignificado
waitingEsperando o primeiro código.
code_receivedCódigo recebido. Códigos novos entram em codes enquanto a ativação estiver aberta.
completedFinalizada por você (/number/finish).
cancelledCancelada. Valor devolvido.
expiredSem código em 20 min. Valor devolvido automaticamente.

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.
  • Status: consulte a cada 5 s. Mais rápido não antecipa o código.
Guias

Fluxo de compra

  1. GET /services?country=73: serviços do país e preço inicial.
  2. GET /offers?country=73&service=wa (opcional): faixas de preço e estoque.
  3. GET /number/get?country=73&service=wa&request_id=...: compra e devolve phone e id.
  4. GET /number/status?id=ID a cada 5 s, até code vir preenchido.
  5. Com código: GET /number/finish?id=ID. Sem código: GET /number/cancel?id=ID (libera 2 min após a compra) e o valor volta ao saldo.

Esperando o código

Consulte /number/status a cada 5 s e pare quando code vier preenchido ou state virar cancelled, expired ou completed.

  • Defina um prazo máximo no seu código (20 min).
  • Com vários números, use /activations?state=active. Uma chamada traz todas as ativas.
  • Uma ativação pode receber mais de um código. Leia codes[].

Compra em lote

quantity=N compra N números numa chamada, até 50. Compra parcial é normal: se o estoque ou o saldo acabar no meio, o resto não é cobrado.

  • A resposta traz numbers[], requested, purchased e failed.
  • errors lista o motivo das falhas, quando houver.
  • Limite de 50 números por minuto por conta.
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"

Idempotência (request_id)

Mande request_id em toda compra. Se der timeout e você não sabe se a compra saiu, repita a mesma chamada com a mesma request_id. A API devolve a resposta original, com o header Idempotent-Replay: true, e não cobra de novo.

  • Compra nova, request_id nova.
  • 8 a 80 caracteres (letras, números, _ . : -). O header Idempotency-Key também vale.
  • A chave dura 24 h e só é salva quando a compra deu certo. Compra que falhou pode ser repetida.
  • Mesma chave com parâmetros diferentes: request_id_reutilizada.

Exemplo completo

Compra, espera o código e finaliza. Se o código não chega, cancela. A compra usa request_id, então repetir a chamada não 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
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."
fi

Boas práticas

  • Token em variável de ambiente. Nunca no código, no front-end ou em repositório.
  • request_id em toda compra. Repetiu a chamada? Mesma request_id.
  • Polling de 5 s, com prazo máximo.
  • Vários números: /activations?state=active em vez de um /number/status por ativação.
  • Trate error, não message.
  • 429: espere retry_in_seconds. 502: tente de novo com espera crescente (2 s, 4 s, 6 s).
  • Use max_price_brl como teto. Preço e estoque mudam, então consulte /offers antes de lotes grandes.
  • Confira /balance antes de lotes grandes.
  • Guarde request_id e id da ativação nos logs.
  • Cancele só o que não vai usar. Depois do primeiro código não há reembolso.
Referência das rotas

Conta

GET
/api/v1/balance

Saldo

Saldo e totais da conta.

Campos da resposta

CampoTipoDescrição
balance_brlnumberSaldo disponível.
total_spent_brlnumberTotal gasto na conta.
total_recharged_brlnumberTotal recarregado.
currencystringSempre "BRL".

Exemplo

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 .

Resposta

{
  "status": "success",
  "balance_brl": 25.4,
  "total_spent_brl": 12.1,
  "total_recharged_brl": 37.5,
  "currency": "BRL"
}

Testar

GET
/api/v1/profile

Perfil

Usuário, saldo e data de criação.

Campos da resposta

CampoTipoDescrição
usernamestringUsuário.
balance_brlnumberSaldo disponível.
created_atstringCriação da conta (ISO 8601).
reseller.levelintegerNível atual (0 a 3). 0 = preço normal.
reseller.markup_discount_percentnumberDesconto na taxa de serviço, em %.
reseller.permanent_levelintegerNível permanente conquistado (0, 2 ou 3).
reseller.week_recharged_brlnumberMaior recarga única desde a última revisão semanal.
reseller.lifetime_recharged_brlnumberTotal recarregado na conta (R$).
reseller.next_reviewstringPróxima revisão semanal (terça 02:00, no fuso da conta).

Exemplo

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 .

Resposta

{
  "status": "success",
  "username": "maria",
  "balance_brl": 25.4,
  "created_at": "2026-09-01T12:00:00.000Z"
}

Testar

Catálogo

GET
/api/v1/countries

Países

Lista de países. Use o id em country.

Campos da resposta

CampoTipoDescrição
countries[].idintegerID do país. Use em country.
countries[].namestringNome.
countries[].dial_codestring | nullDDI, ex.: +55.

Exemplo

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 .

Resposta

{
  "status": "success",
  "countries": [
    {
      "id": 73,
      "name": "Brasil",
      "dial_code": "+55"
    }
  ]
}

Testar

GET
/api/v1/services

Serviços

Serviços de um país, com estoque e preço inicial. Use code em service.

Parâmetros

NomeDescrição
countryobrigatórioID do país.

Campos da resposta

CampoTipoDescrição
countryintegerPaís consultado.
services[].codestringCódigo. Use em service.
services[].namestringNome.
services[].availableintegerEstoque.
services[].from_price_brlnumber | nullPreço da oferta mais barata.

Erros

Exemplo

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 .

Resposta

{
  "status": "success",
  "country": 73,
  "services": [
    {
      "code": "wa",
      "name": "WhatsApp",
      "available": 1240,
      "from_price_brl": 7.1
    }
  ]
}

Testar

GET
/api/v1/operators

Operadoras

Operadoras de um país. Uso opcional em operator na compra.

Parâmetros

NomeDescrição
countryobrigatórioID do país.

Campos da resposta

CampoTipoDescrição
countryintegerPaís consultado.
operators[].idstringID da operadora. Use em operator.
operators[].namestringNome.

Erros

Exemplo

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 .

Resposta

{
  "status": "success",
  "country": 73,
  "operators": [
    {
      "id": "vivo",
      "name": "vivo"
    }
  ]
}

Testar

GET
/api/v1/countries/top

Melhores países

Países com estoque para um serviço, na ordem do provedor, com o seu preço inicial.

Parâmetros

NomeDescrição
serviceobrigatórioCódigo do serviço (veja /services).
limitopcionalMáximo de itens. Padrão 15, máx. 50.

Campos da resposta

CampoTipoDescrição
servicestringServiço consultado.
countries[].countryintegerID do país.
countries[].namestringNome do país.
countries[].availableintegerEstoque.
countries[].from_price_brlnumberPreço da oferta mais barata, em reais.

Erros

Exemplo

curl "https://kdefy-sms.com/api/v1/countries/top?service=wa" \
  -H "X-API-Key: $KDEFY_API_KEY"
const res = await fetch("https://kdefy-sms.com/api/v1/countries/top?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/countries/top",
    params={"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/countries/top?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/countries/top?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/countries/top" \
  -H "X-API-Key: $KDEFY_API_KEY" \
  --data-urlencode "service=wa" | jq .

Resposta

{
  "status": "success",
  "service": "wa",
  "countries": [
    {
      "country": 73,
      "name": "Brasil",
      "available": 1200,
      "from_price_brl": 6.9
    }
  ]
}

Testar

GET
/api/v1/offers

Ofertas

Faixas de preço e estoque de um serviço num país. Faixas baratas têm pouco estoque; as mais caras tendem a ter número.

Parâmetros

NomeDescrição
countryobrigatórioID do país.
serviceobrigatórioCódigo do serviço.

Campos da resposta

CampoTipoDescrição
offers[].price_brlnumberPreço da faixa.
offers[].availableintegerEstoque da faixa.

Erros

Exemplo

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 .

Resposta

{
  "status": "success",
  "country": 73,
  "service": "wa",
  "offers": [
    {
      "price_brl": 7.1,
      "available": 12
    },
    {
      "price_brl": 8.4,
      "available": 340
    }
  ]
}

Testar

Números

GETPOST
/api/v1/number/get

Comprar número

Compra um número, ou vários com quantity. Debita na hora. Se o número cancelar ou expirar sem código, o valor volta ao saldo.

Lote e repetição segura: veja Compra em lote e Idempotência em Guias.

Parâmetros

NomeDescrição
countryobrigatórioID do país.
serviceobrigatórioCódigo do serviço.
max_price_brlopcionalTeto de preço. Usa a faixa mais cara que couber nele. Sem isso, usa a mais barata.
operatoropcionalOperadora. Padrão: qualquer. Restringe o estoque.
quantityopcionalQuantidade, de 1 a 50. Sem isso compra 1 e a resposta vem no formato simples.
request_idopcionalChave anti-duplicação, 8 a 80 caracteres. O header Idempotency-Key também vale. Recomendada.

Campos da resposta

CampoTipoDescrição
idstringID da ativação. Vai em /number/status, /number/cancel e /number/finish.
servicestringCódigo do serviço.
service_namestringNome do serviço. Vem do provedor, não é traduzido.
countryintegerID do país.
country_namestringNome do país.
phonestringNúmero com DDI, só dígitos (5511999999999).
statestringEstado da ativação (veja Estados). Valor fixo em inglês; use este na lógica.
state_labelstringEstado em texto, no idioma da conta. Só para exibir.
codestring | nullÚltimo código recebido. null enquanto não chegou.
codesarrayTodos os códigos, [{ code, received_at }], do mais antigo ao mais novo.
price_brlnumberValor cobrado, em reais.
seconds_leftintegerSegundos até a ativação expirar.
cancel_in_secondsintegerSegundos até liberar o cancelamento. 0 = já pode.
balance_brlnumberSaldo depois da compra.
com quantity
requestedintegerQuantidade pedida.
purchasedintegerQuantidade comprada.
failedintegerQuantidade não comprada (não é cobrada).
numbersarrayAtivações, com os mesmos campos acima.
errorsarrayCódigos de erro das compras que falharam (compra parcial).

Erros

Exemplo

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 .

Resposta

{
  "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
}

Resposta com 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
}

Testar

GET
/api/v1/number/status

Status e código

Estado da ativação e códigos recebidos.

Parâmetros

NomeDescrição
idobrigatórioID da ativação, vem da compra.

Campos da resposta

CampoTipoDescrição
idstringID da ativação. Vai em /number/status, /number/cancel e /number/finish.
servicestringCódigo do serviço.
service_namestringNome do serviço. Vem do provedor, não é traduzido.
countryintegerID do país.
country_namestringNome do país.
phonestringNúmero com DDI, só dígitos (5511999999999).
statestringEstado da ativação (veja Estados). Valor fixo em inglês; use este na lógica.
state_labelstringEstado em texto, no idioma da conta. Só para exibir.
codestring | nullÚltimo código recebido. null enquanto não chegou.
codesarrayTodos os códigos, [{ code, received_at }], do mais antigo ao mais novo.
price_brlnumberValor cobrado, em reais.
seconds_leftintegerSegundos até a ativação expirar.
cancel_in_secondsintegerSegundos até liberar o cancelamento. 0 = já pode.

Erros

Exemplo

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 .

Resposta

{
  "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
}

Testar

GET
/api/v1/number/reactivate/options

Reativar: preço

Mostra quanto custa reativar o número de uma ativação finalizada que recebeu código.

Parâmetros

NomeDescrição
idobrigatórioID da ativação original (finalizada, com código).

Campos da resposta

CampoTipoDescrição
idstringID da ativação original.
servicestringCódigo do serviço.
countryintegerID do país.
price_brlnumberPreço atual da reativação, em reais.

Erros

Exemplo

curl "https://kdefy-sms.com/api/v1/number/reactivate/options?id=1842" \
  -H "X-API-Key: $KDEFY_API_KEY"
const res = await fetch("https://kdefy-sms.com/api/v1/number/reactivate/options?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/reactivate/options",
    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/reactivate/options?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/reactivate/options?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/reactivate/options" \
  -H "X-API-Key: $KDEFY_API_KEY" \
  --data-urlencode "id=1842" | jq .

Resposta

{
  "status": "success",
  "id": "1842",
  "service": "wa",
  "country": 73,
  "price_brl": 3.1
}

Testar

GETPOST
/api/v1/number/reactivate

Reativar número

Reaproveita o número de uma ativação finalizada para receber um novo código. Debita o preço atual na hora e cria uma nova ativação.

Veja o preço antes em /number/reactivate/options.

Parâmetros

NomeDescrição
idobrigatórioID da ativação original.
max_price_brlopcionalPreço máximo aceito. Se o valor atual for maior, nada é cobrado.

Campos da resposta

CampoTipoDescrição
idstringID da ativação. Vai em /number/status, /number/cancel e /number/finish.
servicestringCódigo do serviço.
service_namestringNome do serviço. Vem do provedor, não é traduzido.
countryintegerID do país.
country_namestringNome do país.
phonestringNúmero com DDI, só dígitos (5511999999999).
statestringEstado da ativação (veja Estados). Valor fixo em inglês; use este na lógica.
state_labelstringEstado em texto, no idioma da conta. Só para exibir.
codestring | nullÚltimo código recebido. null enquanto não chegou.
codesarrayTodos os códigos, [{ code, received_at }], do mais antigo ao mais novo.
price_brlnumberValor cobrado, em reais.
seconds_leftintegerSegundos até a ativação expirar.
cancel_in_secondsintegerSegundos até liberar o cancelamento. 0 = já pode.
reactivated_fromstringID da ativação original.
balance_brlnumberSaldo depois da cobrança.

Erros

Exemplo

curl "https://kdefy-sms.com/api/v1/number/reactivate?id=1842" \
  -H "X-API-Key: $KDEFY_API_KEY"
const res = await fetch("https://kdefy-sms.com/api/v1/number/reactivate?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/reactivate",
    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/reactivate?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/reactivate?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/reactivate" \
  -H "X-API-Key: $KDEFY_API_KEY" \
  --data-urlencode "id=1842" | jq .

Resposta

{
  "status": "success",
  "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,
  "reactivated_from": "1842",
  "balance_brl": 6.4
}

Testar

GETPOST
/api/v1/number/cancel

Cancelar

Cancela e devolve o valor. Só sem código e 2 min após a compra; antes disso responde cancelamento_muito_cedo com retry_in_seconds. Na API não há multa por cancelamentos seguidos.

Parâmetros

NomeDescrição
idobrigatórioID da ativação.

Campos da resposta

CampoTipoDescrição
idstringID da ativação.
statestringSempre "cancelled".
refunded_brlnumberValor devolvido.
balance_brlnumberSaldo depois do reembolso.

Erros

Exemplo

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 .

Resposta

{
  "status": "success",
  "id": "1842",
  "state": "cancelled",
  "refunded_brl": 8.4,
  "balance_brl": 25.4
}

Testar

GETPOST
/api/v1/number/finish

Finalizar

Encerra a ativação depois do código. Para de esperar códigos extras. Sem reembolso.

Parâmetros

NomeDescrição
idobrigatórioID da ativação.

Campos da resposta

CampoTipoDescrição
idstringID da ativação.
statestringSempre "completed".

Erros

Exemplo

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 .

Resposta

{
  "status": "success",
  "id": "1842",
  "state": "completed"
}

Testar

Histórico

GET
/api/v1/activations

Listar ativações

Suas ativações, inclusive as do site, da mais nova para a mais antiga.

Parâmetros

NomeDescrição
stateopcionalFiltra por estado: active, waiting, code_received, completed, cancelled ou expired.
serviceopcionalFiltra por código do serviço.
countryopcionalFiltra por ID do país.
fromopcionalSó ativações criadas a partir desta data (ISO 8601).
toopcionalSó ativações criadas antes desta data (ISO 8601).
pageopcionalPágina, começando em 1. Use junto com limit.
limitopcionalMáximo de itens. Padrão 50, máx. 100.

Campos da resposta

CampoTipoDescrição
activations[]arrayAtivações, com os mesmos campos de /number/status.

Exemplo

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 .

Resposta

{
  "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
    }
  ]
}

Testar

GET
/api/v1/stats

Estatísticas

Total de ativações, taxa de sucesso e gasto por serviço e país num período.

Parâmetros

NomeDescrição
fromopcionalInício do período (data ISO 8601). Padrão: 30 dias atrás.
toopcionalFim do período (data ISO 8601). Padrão: agora.

Campos da resposta

CampoTipoDescrição
fromstringInício do período (data ISO 8601). Padrão: 30 dias atrás.
tostringFim do período (data ISO 8601). Padrão: agora.
totalintegerAtivações no período.
successintegerAtivações que receberam código.
success_percentnumberTaxa de sucesso, de 0 a 100.
spent_brlnumberGasto com ativações que receberam código.
by_service_countryarrayDetalhe por serviço e país: { service, service_name, country, country_name, count, success, success_percent }.

Exemplo

curl "https://kdefy-sms.com/api/v1/stats" \
  -H "X-API-Key: $KDEFY_API_KEY"
const res = await fetch("https://kdefy-sms.com/api/v1/stats", {
  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/stats",
    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/stats");
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/stats")
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/stats" \
  -H "X-API-Key: $KDEFY_API_KEY" | jq .

Resposta

{
  "status": "success",
  "total": 40,
  "success": 36,
  "success_percent": 90,
  "spent_brl": 120.5,
  "by_service_country": [
    {
      "service": "wa",
      "service_name": "WhatsApp",
      "country": 73,
      "country_name": "Brasil",
      "count": 40,
      "success": 36,
      "success_percent": 90
    }
  ]
}

Testar

GET
/api/v1/transactions

Extrato

Recargas, compras e reembolsos.

Parâmetros

NomeDescrição
limitopcionalMáximo de itens. Padrão 50, máx. 200.

Campos da resposta

CampoTipoDescrição
transactions[].typestringTipo (PURCHASE, REFUND...).
transactions[].amount_brlnumberValor.
transactions[].balance_after_brlnumberSaldo depois.
transactions[].descriptionstringDescrição.
transactions[].created_atstringData (ISO 8601).

Exemplo

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 .

Resposta

{
  "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"
    }
  ]
}

Testar

Erros

Formato: { "status": "error", "error": "saldo_insuficiente", "message": "..." }. Decida pelo campo error.

HTTPerrorQuandoO que fazer
401token_nao_informado token_invalido Token ausente, inválido ou revogado.Corrija o token. Não repita.
403conta_bloqueada token_suspenso Conta banida ou API suspensa pelo admin.Fale com o suporte.
400pais_invalido servico_invalido id_invalido quantidade_invalida preco_invalido operador_invalido request_id_invalido Parâmetro ausente ou inválido.Corrija a chamada.
402saldo_insuficiente Saldo menor que o preço.Recarregue no site.
404sem_numeros_disponiveis oferta_indisponivel Sem estoque nessa faixa agora.Suba max_price_brl, troque o país ou tente depois.
404ativacao_nao_encontrada ID inexistente ou de outra conta.Confira o id.
409requisicao_em_andamento A request_id ainda está sendo processada.Espere e repita a mesma chamada.
409cancelamento_muito_cedo Menos de 2 min desde a compra.Espere retry_in_seconds.
409ativacao_nao_reativavel reativacao_indisponivel Só números de ativações finalizadas com código podem ser reativados, e o provedor precisa liberar.Consulte /number/reactivate/options.
409ativacao_nao_cancelavel ativacao_nao_finalizavel O estado atual não permite a ação.Consulte /number/status.
422request_id_reutilizada Mesma request_id com parâmetros diferentes.Use uma request_id nova.
422preco_acima_do_maximo O preço atual é maior que o max_price_brl.Suba o max_price_brl.
422preco_abaixo_do_minimo max_price_brl menor que a oferta mais barata.Suba para min_price_brl ou mais.
429limite_de_requisicoes limite_de_numeros Passou do limite.Espere retry_in_seconds.
502falha_temporaria Instabilidade. Você não é cobrado.Repita com espera crescente, mesma request_id.
Ajuda

Perguntas frequentes

Quanto o código demora?

Em geral segundos, mas depende do serviço. A ativação espera até 20 min. Sem código nesse prazo, expira e o valor volta ao saldo.

Dei timeout na compra. E agora?

Repita a mesma chamada com a mesma request_id: a resposta original volta e nada é cobrado de novo. Se você não usou request_id, liste /activations?state=active antes de comprar outra vez.

Posso cancelar logo depois de comprar?

Não. O cancelamento libera 2 min após a compra. cancel_in_seconds mostra quanto falta.

sem_numeros_disponiveis com saldo. Por quê?

A faixa de preço está sem estoque agora. Suba max_price_brl, troque o país ou veja onde há estoque em /offers.

O preço muda entre a consulta e a compra?

Pode mudar. Vale o price_brl da resposta da compra, e max_price_brl impede que passe do seu teto.

Preciso de request_id?

Não é obrigatória, mas use em qualquer automação. Sem ela, repetir a chamada por engano compra duas vezes.

Dá para comprar mais de 50 números?

Não numa requisição, e o teto é 50 por minuto por conta. Acima disso a API responde limite_de_numeros.

Por que a resposta vem em português?

message e state_label seguem o idioma da conta. Force com ?lang=pt, ?lang=en, ?lang=es, ?lang=de ou ?lang=fr. Chaves do JSON, state e códigos de erro são sempre os mesmos.

Como recarrego o saldo?

Pelo site, com PIX. O saldo da API é o mesmo do site.

O token vazou.

Gere outro em API, no site. O antigo para de funcionar na hora. Se viu uso estranho, fale com o suporte.

Regras de uso

  • Cada ativação espera o código por até 20 min. Sem código, expira e o valor volta ao saldo.
  • Depois do primeiro código não há reembolso.
  • Você só enxerga e opera as suas ativações.
  • Recarga de saldo é pelo site (PIX).
  • Toda requisição fica registrada na conta. O admin consulta o uso do token.
  • Abuso ou fraude pode bloquear a conta.