Checklist pré-execução
Verifique antes para evitar retrabalho.
- Um e-mail ativo para o cadastro.
- Tenha um ambiente de execução: Python 3, JDK 15 ou superior (blocos de texto), Go ou PHP com curl.
- Confirme que é maior de 18 anos, pois o serviço é exclusivo para usuários adultos.
- Entenda que é apenas um modelo de chat de texto puro: sem embeddings, imagem, áudio ou fine-tuning.
- Armazene a chave em variáveis de ambiente, não no código fonte ou repositórios.
As convenções da API são mínimas: o endpoint é https://api.wushenchaapi.com/v1. O formato é compatível com chat completion da OpenAI, então você pode reutilizar quase todo o corpo da requisição que já escreveu.
Estimativa de tempo: registro em um minuto; instalação depende do seu ambiente; a primeira requisição leva no máximo 30 segundos. Se demorar mais, verifique rede ou chave e consulte o checklist de erros. Ordem: primeiro models, depois chat; síncrono antes de streaming. Confirme cada etapa antes de prosseguir.
Cadastro e obtenção da chave
Acesse /get-api-key/ e registre-se com e-mail e senha. A chave é exibida imediatamente após o registro; copie-a. Detalhes:
- Cada conta possui apenas uma chave de API.
- Você pode regenerar a chave, mas a antiga será invalidada imediatamente. Implante o novo valor antes de trocar em produção.
- Novo usuário recebe $0.50 de crédito de teste grátis, válido por 7 dias. Não é necessário preencher informações de pagamento.
- Ao expirar ou acabar, a resposta será 402 (erro
no_credit). Recarregue seu crédito pré-pago. Não é assinatura; o saldo não expira.
Defina a variável de ambiente: macOS/Linux export API_KEY=chave; Windows PowerShell $env:API_KEY="chave". Todos os exemplos usam API_KEY.
Passo 1: Verificar conectividade com /v1/models
Não envie conversas ainda. Faça uma requisição GET de custo zero para confirmar endereço, rede e chave:
curl https://api.wushenchaapi.com/v1/models \
-H "Authorization: Bearer $API_KEY"Retorno 200 com a lista de modelos (apenas uncensored) indica sucesso. 401 indica chave inválida ou ausente; timeout indica problemas de rede ou proxy. Separe problemas de conexão e corpo da requisição para ganhar tempo na integração.
Python: requests
Basta requests.post. Atenção: defina timeout; verifique r.ok antes de acessar choices; erros retornam {"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"])Em sucesso, usage contém prompt_tokens e completion_tokens. Imprima para monitorar custos.
Análise campo a campo do corpo da requisição
As quatro linguagens enviam o mesmo JSON. Entenda-o para traduzir facilmente para qualquer linguagem.
| Campo | Obrigatório | Descrição |
|---|---|---|
| model | Sim | Fixo em uncensored. |
| messages | Sim | Array de objetos, cada um contendo role e content. Roles: system, user, assistant. |
| max_tokens | Não | Padrão 2048, limite máximo 16.000. Você deve aumentar manualmente para textos longos. |
| temperature / top_p / stop | Não | Parâmetros padrão de amostragem, repassados diretamente. |
| stream | Não | Quando true, utiliza streaming SSE. |
Leia três campos da resposta: choices[0].message.content é o conteúdo; choices[0].finish_reason indica término normal ou truncamento por limite de tamanho; usage mostra o consumo de tokens. Leia todos para uma integração completa.
Há duas limitações rígidas: corpo da requisição até 8 MB e limite de 300 requisições por minuto por chave. Para tarefas em lote, defina um limite de concorrência simples em vez de enviar requisições simultâneas indiscriminadamente.
Java: java.net.http
JDK 11+ tem HttpClient. JDK 15+ usa blocos de texto. Versões antigas usam strings.
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());
}
}Dica: com conteúdo chinês, BodyPublishers.ofString usa UTF-8 por padrão. Em produção, reutilize HttpClient como singleton, não crie novas instâncias a cada pedido.
Go: net/http
A biblioteca padrão do Go também é suficiente. O ponto crítico é não usar http.DefaultClient sem definir timeout, caso contrário, as goroutines ficarão penduradas se o servidor remoto demorar.
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))
}Leia o corpo da resposta com io.ReadAll antes de processar. Para manipulação estruturada, defina structs correspondentes e use encoding/json para desserialização, mapeando os campos choices, message, content e usage.
PHP: curl
Use a extensão curl do PHP. Lembre-se de adicionar JSON_UNESCAPED_UNICODE ao json_encode, caso contrário, o chinês será convertido para \uXXXX. Funciona, mas fica difícil de 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";Diferencie dois tipos de falha: curl_exec retornando false indica problema na camada de rede; retornar conteúdo com código de status diferente de 200 indica problema na camada da API, onde você deve ler o error.code.
Erros comuns na primeira chamada
- 401: O cabeçalho está
Authorization: chave, faltando o prefixoBearer; ou a variável de ambiente não foi carregada no novo terminal. - 404: O caminho está faltando
/v1ouchat/completionsestá digitado incorretamente. - 400: JSON inválido ou o prompt com max_tokens excede o limite de 100.000 tokens.
- 402: Saldo insuficiente ou crédito de teste expirado.
- Saída truncada:
max_tokenstem valor padrão de 2048, com máximo de 16.000 por chamada. Para textos longos, ajuste esse valor explicitamente. - Deseja streaming: Adicione
"stream": trueao corpo da requisição. A resposta será SSE e incluirá automaticamente um bloco de dados com usage ao final.
Após a execução, o próximo passo é ver Como escrever prompts para ajustar a qualidade da saída. Para erros, consulte o Guia de resolução de erros. A descrição completa dos parâmetros está na documentação e os preços estão na página de preços.
Após confirmar o funcionamento, adicione três itens antes de ir para produção
Os exemplos do tutorial são a versão mínima funcional. Para integrar em produção, adicione pelo menos estes três itens.
- Timeout. O exemplo usa 120 segundos porque a geração de texto longo é lenta. Se seu sistema espera síncronamente, reduza o tempo conforme a tolerância da sua aplicação e use streaming para que o usuário veja o texto sendo gerado.
- Roteamento de erros.401, 402, 403 exigem alerta ou aviso ao usuário. 429 e 503 merecem retry com backoff. Detalhes no manual de troubleshooting.
- Registro de uso. Registre uma linha de log com o campo usage de cada resposta. Anote apenas os números, não o conteúdo do usuário. Isso é essencial para conferência mensal e análise de consumo anômalo.
Sobre gestão de chaves: há apenas uma chave. Se ela for comprometida, deve ser regenerada, o que derruba todos os serviços que a utilizam simultaneamente. Não a espalhe por scripts ou configurações de várias máquinas; centralize-a em um único local de configuração para facilitar a troca sem falhas.
Sobre limites de conteúdo: conteúdo adulto legal, ficção e tópicos controversos não são bloqueados. No entanto, conteúdo sexual envolvendo menores é sempre bloqueado com resposta 403, incluindo ficção e roleplay. Se seu aplicativo é voltado para adultos, recomendamos implementar verificação de idade no fluxo de cadastro.
Aqui está uma sequência de verificação para colar perto do monitor: a chave está na variável de ambiente? O endpoint models responde? O corpo da requisição é JSON válido? O modelo é sem censura? max_tokens está suficiente? finish_reason na resposta é stop ou length? O usage foi registrado? Se todos os sete itens estiverem verdes, a integração está concluída.