ES ▾
Obtener clave de API

Tutorial de API sin censura: registro, verificación y primera llamada

Este tutorial tiene un solo objetivo: que ejecutes tu primera petición en diez minutos. Sin rodeos con SDKs; usa directamente las bibliotecas estándar de cada lenguaje para enviar peticiones HTTP, ya que solo hay un endpoint POST. Si ves cómo luce la petición, no te perderás al cambiar de framework. Los ejemplos cubren Python requests, Java java.net.http, Go net/http y PHP curl; copia y ejecuta el código.

Actualizado el

Puntos clave

  • El registro solo requiere correo y contraseña. La cuenta nueva recibe $0.50 de crédito de prueba válido por 7 días, sin necesidad de vincular un método de pago.
  • La Base URL es https://api.wushenchaapi.com/v1,模型名固定写 uncensored y el encabezado de autenticación es Authorization: Bearer.
  • Verifica primero la clave con GET /v1/models y luego haz la petición POST /v1/chat/completions; separar estos pasos acelera la depuración.
  • En los cuatro lenguajes debes configurar un tiempo de espera y leer error.code en lugar de confiar solo en el código de estado HTTP.

Lista de verificación previa

Repásala antes de empezar para evitar retrocesos.

  • Un correo electrónico activo para el registro.
  • Requisito: tener un entorno de ejecución disponible: Python 3, JDK 15 o superior (para usar bloques de texto), Go, o PHP con la extensión curl.
  • Ser mayor de 18 años, ya que el servicio es exclusivo para adultos.
  • Saber que buscas conversación de texto puro: hay un solo modelo, sin embeddings, imágenes, audio ni fine-tuning.
  • Usar variables de entorno para la clave, no guardarla en el código ni subirla al repositorio.

El contrato de la API es mínimo: la URL es https://api.wushenchaapi.com/v1 y es compatible con el formato de finalización de chat de OpenAI, por lo que puedes reutilizar casi todo tu cuerpo de petición anterior.

Estimación de tiempo: el registro toma un minuto, la instalación depende de tu entorno, y la primera petición en sí misma no supera los 30 segundos. Si tarda más, suele ser un problema de red o de clave; salta a la lista de solución de problemas al final. Sigue este orden: primero models, luego chat, primero síncrono, luego streaming.

Registro y obtención de la clave

Visita /get-api-key/ y regístrate con correo y contraseña. La clave se muestra al instante; cópiala. Detalles importantes:

  1. Cada cuenta tiene una sola clave de API.
  2. Puedes regenerarla, pero la anterior caducará inmediatamente. Despliega el nuevo valor antes de cambiarlo en producción.
  3. La cuenta nueva incluye $0.50 de crédito de prueba válido por 7 días, sin necesidad de datos de pago.
  4. Si el crédito se agota o vence, recibirás un 402 con el código no_credit. Recarga tu crédito prepago para continuar; no es suscripción y el saldo no caduca.

Guarda la clave en variables de entorno: en macOS/Linux ejecuta export API_KEY=tu_clave, en Windows PowerShell usa $env:API_KEY="tu_clave". Todos los ejemplos leen desde API_KEY.

Paso 1: verificar conectividad con /v1/models

No envíes chats aún. Haz primero una petición GET sin costo para confirmar que la URL, la red y la clave funcionan:

curl https://api.wushenchaapi.com/v1/models \
  -H "Authorization: Bearer $API_KEY"

Si recibes 200 y la lista de modelos (solo uncensored), estás conectado. Un 401 indica clave incorrecta o ausente; un timeout indica problemas de red o proxy. Separar los problemas de conectividad de los del cuerpo de la petición es el hábito que más tiempo te ahorra.

Python: requests

Sin SDK, un requests.post basta. Tres puntos: timeout obligatorio; verifica r.ok antes de choices; error: {"error":{"code":...,"message":...}}.

import os
import requests

url = "https://api.wushenchaapi.com/v1/chat/completions"
headers = {
    "Authorization": "Bearer " + os.environ["API_KEY"],
    "Content-Type": "application/json",
}
payload = {
    "model": "uncensored",
    "messages": [{"role": "user", "content": "用两句话描述一场雨夜里的追逐戏。"}],
    "max_tokens": 300,
}
r = requests.post(url, headers=headers, json=payload, timeout=120)
print(r.status_code)
data = r.json()
if r.ok:
    print(data["choices"][0]["message"]["content"])
    print(data["usage"])
else:
    print(data["error"]["code"], data["error"]["message"])

En caso de éxito, usage contiene prompt_tokens y completion_tokens. Se recomienda imprimir estos valores en cada ejecución para tener control sobre los costos.

Análisis campo por campo del cuerpo de la petición

Los cuatro lenguajes envían el mismo JSON. Entiéndelo primero; luego es solo traducir la sintaxis.

CampoObligatorioDescripción
modelSíFijo en uncensored.
messagesSíArray de objetos con role y content. Roles válidos: system, user, assistant.
max_tokensNoPor defecto 2048, máximo 16,000. Ajusta este valor para textos largos.
temperature / top_p / stopNoParámetros de muestreo estándar que se reenvían tal cual.
streamNoCuando es true, se usa streaming SSE.

Lo que más sueles leer en la respuesta son tres campos: choices[0].message.content es el contenido, choices[0].finish_reason indica si finalizó normalmente o por truncamiento, y usage muestra el consumo de tokens. Leer los tres asegura una integración completa.

Ten en cuenta estas limitaciones estrictas: el cuerpo de la petición no debe superar los 8 MB y tienes un límite de 300 peticiones por minuto para cada clave. No lances todas las tareas en paralelo de golpe; establece primero un límite de concurrencia.

Java: java.net.http

JDK 11 incluye HttpClient sin dependencias externas. Los ejemplos usan bloques de texto de JDK 15 para JSON; en versiones inferiores puedes usar concatenación de cadenas o tu librería JSON familiar para serializar.

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;

public class Demo {
    public static void main(String[] args) throws Exception {
        String key = System.getenv("API_KEY");
        String body = """
            {"model":"uncensored",
             "messages":[{"role":"user","content":"写一段两百字以内的悬疑小说开头。"}],
             "max_tokens":400}
            """;
        HttpRequest req = HttpRequest.newBuilder(
                URI.create("https://api.wushenchaapi.com/v1/chat/completions"))
            .timeout(Duration.ofSeconds(120))
            .header("Authorization", "Bearer " + key)
            .header("Content-Type", "application/json")
            .POST(HttpRequest.BodyPublishers.ofString(body))
            .build();
        HttpResponse<String> resp = HttpClient.newHttpClient()
            .send(req, HttpResponse.BodyHandlers.ofString());
        System.out.println(resp.statusCode());
        System.out.println(resp.body());
    }
}

Consejo: cuando el contenido tiene chino, BodyPublishers.ofString usa por defecto codificación UTF-8, no hace falta gestionar nada extra. En producción, convierte HttpClient en un singleton para reutilizarlo; no crees uno nuevo en cada petición.

Go: net/http

La librería estándar de Go también es suficiente. Lo importante es no usar http.DefaultClient sin configurar un tiempo de espera; de lo contrario, las goroutines se quedarán colgadas si el servidor remoto se bloquea.

package main

import (
	"bytes"
	"fmt"
	"io"
	"net/http"
	"os"
	"time"
)

func main() {
	body := []byte(`{"model":"uncensored","messages":[{"role":"user","content":"给一个反派角色写三句独白。"}],"max_tokens":300}`)
	req, err := http.NewRequest("POST", "https://api.wushenchaapi.com/v1/chat/completions", bytes.NewReader(body))
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("API_KEY"))
	req.Header.Set("Content-Type", "application/json")

	client := &http.Client{Timeout: 120 * time.Second}
	resp, err := client.Do(req)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()
	out, _ := io.ReadAll(resp.Body)
	fmt.Println(resp.StatusCode, string(out))
}

Lee el cuerpo de la respuesta con io.ReadAll antes de analizarlo. Para procesarlo de forma estructurada, define la struct correspondiente y deserializa con encoding/json; los campos son choices, message, content y usage.

PHP: curl

PHP usa la extensión curl. Recuerda añadir JSON_UNESCAPED_UNICODE a json_encode; de lo contrario, el chino se convertirá en \uXXXX. Funcionará, pero será difícil de leer al depurar.

<?php
$payload = [
    "model" => "uncensored",
    "messages" => [["role" => "user", "content" => "写一首八行的现代诗,主题是末班地铁。"]],
    "max_tokens" => 300,
];
$ch = curl_init("https://api.wushenchaapi.com/v1/chat/completions");
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 120,
    CURLOPT_HTTPHEADER => [
        "Authorization: Bearer " . getenv("API_KEY"),
        "Content-Type: application/json",
    ],
    CURLOPT_POSTFIELDS => json_encode($payload, JSON_UNESCAPED_UNICODE),
]);
$res = curl_exec($ch);
if ($res === false) {
    die("curl 错误: " . curl_error($ch) . "\n");
}
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
echo $status, "\n";
$data = json_decode($res, true);
echo $data["choices"][0]["message"]["content"] ?? $res, "\n";

Distingue dos tipos de fallo: si curl_exec devuelve false, es un problema de capa de red; si devuelve contenido pero el código de estado no es 200, es un problema de capa de interfaz y debes leer error.code.

Trampas comunes en la primera llamada

  • 401: Escribiste el header Authorization: clave y omitiste el prefijo Bearer ; o la variable de entorno no se aplicó en la nueva terminal.
  • 404: Faltaba /v1 en la ruta, o se escribió mal chat/completions.
  • 400: JSON inválido, o el prompt con max_tokens supera el límite de 100,000 tokens.
  • 402: Saldo agotado o crédito de prueba gratis expirado.
  • Salida truncada: max_tokens tiene un valor por defecto de 2048, con un máximo de 16,000 por llamada; para textos largos debes aumentarlo explícitamente.
  • Quieres streaming: añade "stream": true al cuerpo de la petición. La respuesta es SSE y al final se añade automáticamente un bloque de datos con usage.

Una vez que funcione, el siguiente paso es ver Cómo escribir prompts para mejorar la calidad de la salida. Si encuentras errores, consulta el manual de códigos de error y resolución de problemas. La descripción completa de parámetros está en la documentación y los precios en la página de precios.

Una vez que funcione, añade tres cosas antes de ir a producción

Los ejemplos del tutorial son la versión mínima viable; si vas a integrarlo en un servicio real, al menos añade estos tres elementos.

  1. Tiempo de espera. El ejemplo establece 120 segundos porque la generación de texto largo es lenta. Si tu negocio espera de forma síncrona, reduce el tiempo según la tolerancia de la página y combina con streaming para que el usuario vea el texto primero.
  2. Desvío por error.401, 402 y 403 no se resuelven con reintentos; requieren alerta o aviso al usuario. Solo 429 y 503 justifican reintentos con retroceso. La implementación está en el manual de solución de problemas.
  3. Registro de uso. Registra una línea de log con el usage de cada respuesta. Guarda solo los números, no escribas el contenido del usuario en los logs. Esto es vital para conciliar cuentas a fin de mes y detectar consumos anómalos.

Un último comentario sobre la gestión de claves: solo hay una clave; si se filtra, solo puedes regenerarla, y al regenerarla todos los servicios en uso se desconectan simultáneamente. No la disperses en múltiples scripts o configuraciones de varias máquinas; centralízala en un único lugar de configuración de claves para que el cambio sea limpio y sin omisiones.

Por último, los límites de contenido: el contenido adulto legal, la ficción novelada y los temas controvertidos no se rechazan, pero el contenido sexual que involucre a menores se bloquea siempre, devolviendo 403, incluso en ficción o roleplay. Si tu aplicación está dirigida a adultos, se recomienda añadir una verificación de edad en tu propio flujo de registro.

Te dejo un orden de autoverificación, que puedes pegar al lado del monitor: ¿está la clave en las variables de entorno? ¿Funciona el endpoint de models? ¿Es el cuerpo de la petición un JSON válido? ¿El modelo es uncensored? ¿max_tokens es suficiente? ¿En la respuesta, finish_reason es stop o length? ¿Se ha registrado usage? Si las siete casillas están en verde, la integración está completa.

Preguntas frecuentes

¿Es obligatorio usar el SDK oficial para llamar a la API?

No. Es simplemente un POST HTTPS estándar con JSON; cualquier lenguaje que pueda enviar peticiones HTTP funciona. El SDK solo envuelve la llamada.

¿Qué valor debe tener el campo model?

Escribe siempre uncensored. Actualmente solo hay este modelo; puedes confirmarlo con GET /v1/models.

¿Qué pasa cuando se agota el saldo de prueba?

La petición devuelve 402 con el código de error no_credit. Recarga el saldo de crédito prepago para seguir usando el servicio. El saldo no caduca y no hay suscripciones.

¿Regenerar la clave afecta a la clave anterior?

Sí. La clave anterior queda inválida al instante, así que primero debes actualizar la nueva clave en tus servicios y luego regenerar, o aceptar una breve interrupción.

Solo rellena el formulario para obtener la clave

Crea una cuenta, copia la clave y modifica la Base URL. La configuración es así de sencilla.