KO ▾
API 키 받기

무검열 API 연동 가이드: 등록, 검증, 첫 호출

이 가이드는 단 한 가지 목표만 가집니다: 10분 안에 첫 요청을 성공시키는 것입니다. SDK를 거치지 않고 각 언어의 표준 라이브러리로 HTTP를 직접 사용합니다. 여기에는 POST 엔드포인트가 하나뿐이므로 요청 구조를 이해하면 어떤 프레임워크로 바꿔도 당황하지 않습니다. 예시는 Python의 requests, Java의 java.net.http, Go의 net/http, PHP의 curl을 다룹니다. 모든 코드를 바로 복사해 실행할 수 있습니다.

업데이트

핵심 요약

  • 이메일과 비밀번호만으로 등록 가능하며, 신규 계정에는 $0.50의 무료 체험 크레딧이 제공되며 7일 동안 유효합니다. 결제 정보 연동이 필요하지 않습니다.
  • Base URL은 https://api.wushenchaapi.com/v1,模型名固定写 uncensored이며, 인증 헤더는 Authorization: Bearer를 사용합니다.
  • 먼저 GET /v1/models로 key를 검증한 후 POST /v1/chat/completions을 보내면 빠르게 문제를 분리할 수 있습니다.
  • 네 가지 언어 모두에서 타임아웃을 설정하고 HTTP 상태 코드뿐만 아니라 error.code도 확인해야 합니다.

시작 전 점검 목록

처음부터 확인하여 중간에 돌아오는 시간을 절약하세요.

  • 등록용 이메일 주소가 필요합니다.
  • Python 3, JDK 15 이상(예제에 텍스트 블록 사용), Go, 또는 curl 확장이 있는 PHP 등 본 시스템의 임의의 실행 환경이 필요합니다.
  • 서비스는 성인만 이용 가능하므로 만 18세 이상인지 확인하세요.
  • 순수 텍스트 대화만 원한다는 점을 인지하세요. 여기에는 벡터, 이미지, 음성, 파인튜닝 모델이 없으며 단일 모델만 제공됩니다.
  • 키를 환경 변수에 저장하고 소스 코드에 직접 작성하거나 저장소에 커밋하지 마세요.

인터페이스는 매우 단순합니다. 주소는 https://api.wushenchaapi.com/v1이며, OpenAI의 채팅 완성 API와 호환되므로 기존에 작성한 요청 본문을 그대로 사용할 수 있습니다.

예상 소요 시간: 등록 1분, 환경 설치(본 시스템에 따라 다름), 첫 요청 30초 이내. 이 시간 내에 결과가 없으면 네트워크 또는 키 문제일 수 있으므로 하단 오류 해결 목록으로 이동하세요. 순서를 지키세요: 먼저 models, 다음 chat, 먼저 동기식, 다음 스트리밍. 각 단계를 확인한 후 다음 단계로 진행하세요.

등록 및 키 받기

/get-api-key/로 이동하여 이메일과 비밀번호로 등록하세요. 등록 완료 후 키가 즉시 표시되므로 복사하세요. 몇 가지 주의사항:

  1. 계정당 키는 하나만 생성됩니다.
  2. 키를 재생성할 수 있지만 이전 키는 즉시 무효화되므로, 프로덕션 환경에서 키를 교체하기 전에 새 키를 먼저 배포해야 합니다.
  3. 신규 계정에는 $0.50의 무료 체험 크레딧이 제공되며 7일 동안 유효합니다. 결제 정보 입력이 필요하지 않습니다.
  4. 무료 체험 기간이 만료되거나 크레딧이 소진되면 요청 시 402 오류와 no_credit 오류 코드가 반환됩니다. 선불 크레딧을 충전하면 계속 사용할 수 있으며, 구독이 아닌 선불 방식이므로 잔액은 만료되지 않습니다.

키를 환경 변수에 설정하세요: macOS/Linux에서는 export API_KEY=your_key, Windows PowerShell에서는 $env:API_KEY="your_key"을 실행하세요. 이후 모든 예제에서는 API_KEY에서 값을 읽어옵니다.

1단계: /v1/models로 연결성 검증

채팅 요청을 보내기 전에 비용이 들지 않는 GET 요청을 보내 주소, 네트워크, 키가 모두 정상인지 확인하세요:

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

200 상태 코드와 모델 목록(단일 uncensored 모델 포함)이 반환되면 연결이 성공한 것입니다. 401은 키 오류 또는 누락, 타임아웃은 로컬 네트워크 또는 프록시 문제를 의미합니다. 연결성 문제와 요청 본문 문제를 분리하여 확인하는 것이 연동 단계에서 시간을 절약하는 가장 좋은 방법입니다.

Python: requests

SDK 없이도 requests.post 하나로 충분합니다. 세 가지 주의사항: timeout을 반드시 설정하세요; r.ok을 확인한 후 choices에 접근하세요; 실패 시 응답 본문은 {"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"])

성공 시 usage 필드에 prompt_tokens과 completion_tokens이 포함되므로, 개발 중에는 매번 출력하여 비용 규모를 파악하는 것을 권장합니다.

요청 본문 필드별 분석

네 가지 언어 모두 동일한 JSON을 전송하므로, 먼저 이를 이해하면 어떤 언어로든 쉽게 변환할 수 있습니다.

필드필수설명
model필수uncensored로 고정됩니다.
messages필수배열이며, 각 항목은 role과 content를 포함합니다. role은 system, user, assistant 중 하나여야 합니다.
max_tokens선택기본값은 2048이며, 단일 요청 최대 한도는 16,000입니다. 긴 텍스트 생성 시 직접 늘려야 합니다.
temperature / top_p / stop선택표준 샘플링 매개변수로, 원본 그대로 전달됩니다.
stream아니요true일 때 SSE 스트리밍을 사용합니다.

응답에서 가장 자주 확인하는 세 가지 항목이 있습니다. choices[0].message.content는 본문이며, choices[0].finish_reason는 정상 종료인지 길이로 인해 잘렸는지 알려줍니다. usage은 이번 요청의 토큰 사용량입니다. 세 항목 모두 확인해야 완전한 연동이 완료됩니다.

다음 두 가지 하드 제한 사항을 기억해 두십시오: 요청 본문은 8 MB를 초과할 수 없으며, 키당 분당 300회 요청이 제한됩니다. 대량 작업 시 무작정 동시 요청을 보내지 마십시오. 먼저 간단한 동시 요청 상한선을 설정하십시오.

Java: java.net.http

JDK 11부터 HttpClient가 기본 제공되므로 추가 의존성이 필요하지 않습니다. 아래 예제에서는 JDK 15의 텍스트 블록을 사용하여 JSON을 작성했으며, 구버전에서는 문자열 연결이나 선호하는 JSON 라이브러리를 사용하여 직렬화할 수 있습니다.

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());
    }
}

팁: 본문에 중국어가 포함된 경우, BodyPublishers.ofString은 기본적으로 UTF-8로 인코딩되므로 추가 처리가 필요하지 않습니다. 프로덕션 환경에서는 HttpClient를 싱글톤으로 만들어 재사용하십시오. 매번 요청할 때마다 새로 생성하지 마십시오.

Go: net/http

Go 표준 라이브러리도 충분합니다. 중요한 점은 http.DefaultClient를 사용하되 타임아웃을 설정하지 않는 것입니다. 설정하지 않으면 서버가 응답하지 않을 때 goroutine이 계속 대기하게 됩니다.

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))
}

응답 본문은 io.ReadAll로 모두 읽은 후에 구문 분석하십시오. 구조화된 처리가 필요한 경우, 해당 struct를 정의하여 encoding/json로 역직렬화하면 됩니다. 필드는 choices, message, content, usage 등입니다.

PHP: curl

PHP에서는 curl 확장을 사용하십시오. json_encode에 JSON_UNESCAPED_UNICODE 플래그를 추가해야 합니다. 그렇지 않으면 중국어가 \uXXXX로 변환되는데, 이는 작동은 하지만 디버깅 시 읽기 어렵습니다.

<?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";

두 가지 유형의 실패를 구분하십시오: curl_exec이 false를 반환하면 네트워크 계층 문제입니다. 내용이 반환되었지만 상태 코드가 200이 아니면 API 계층 문제이며, error.code를 읽어야 합니다.

첫 호출 시 자주 발생하는 문제

  • 401: 헤더를 Authorization:密钥로 작성하여 Bearer 접두어를 누락했습니다. 또는 환경 변수가 새로 연 터미널에서 적용되지 않았습니다.
  • 404: 경로에 /v1이 누락되었거나, chat/completions를 오타냈습니다.
  • 400: JSON이 유효하지 않거나, 프롬프트에 max_tokens를 추가하여 100,000 토큰의 상한을 초과했습니다.
  • 402: 잔액이 소진되었거나 무료 체험 기간이 만료되었습니다.
  • 출력 잘림: max_tokens의 기본값은 2048이며, 단일 요청 최대 길이는 16,000입니다. 긴 텍스트를 생성할 때는 명시적으로 값을 크게 설정하십시오.
  • 스트리밍 사용: 요청 본문에 "stream": true을 추가하십시오. 응답은 SSE 형식이며, 마지막에는 자동으로 usage 데이터 블록이 추가됩니다.

연동이 완료되면 다음 단계로 프롬프트 작성법을 확인하여 출력 품질을 조정하십시오. 오류가 발생하면 오류 코드 및 문제 해결 매뉴얼을 참조하십시오. 파라미터 전체 설명은 문서에서, 가격은 가격 페이지에서 확인하십시오.

연동이 완료되면 서비스 출시 전에 다음 세 가지를 보완하십시오.

튜토리얼의 예제는 최소한의 사용 가능한 버전입니다. 실제 서비스에 적용하려면 다음 세 가지 항목을 반드시 보완해야 합니다.

  1. 시간 초과: 예제에서는 긴 텍스트 생성 속도를 고려해 120초로 설정했습니다. 동기 대기 방식이라면 페이지 허용 시간 내에 단축하고 스트리밍을 함께 사용해 사용자가 먼저 결과를 볼 수 있게 하세요.
  2. 오류 분기 처리.401, 402, 403은 재시도해도 효과가 없는 오류이므로 경보를 발생하거나 사용자에게 알려야 합니다. 429과 503만 백오프 재시도가 적합합니다. 구체적인 구현 방법은 문제 해결 매뉴얼에 나와 있으며 여기서는 생략합니다.
  3. 사용량 기록.매번 응답의 usage를 로그에 한 줄로 기록하십시오. 숫자만 기록하고 사용자 내용은 로그에 기록하지 마십시오. 월말 정산 및 이상 사용량 확인에 필요합니다.

키 관리에 대해 한 가지 더 말씀드립니다. 키는 하나뿐이며 유출 시 재생성해야 합니다. 재생성 시 현재 사용 중인 모든 서비스가 동시에 중단됩니다. 따라서 키를 여러 스크립트와 여러 머신의 설정에 흩어지게 두지 마십시오. 키 설정을 중앙 집중화하여 교체 시 누락되지 않도록 하십시오.

마지막으로 콘텐츠 경계에 대해 설명합니다. 합법적인 성인 콘텐츠, 소설의 가상 설정, 논쟁적인 주제는 거부되지 않지만, 미성년자 관련 성 콘텐츠는 모두 차단되며 403 오류를 반환합니다. 가상 설정이나 역할극도 예외는 아닙니다. 귀하의 애플리케이션이 성인 사용자를 대상으로 한다면 등록 프로세스에 연령 확인 절차를 추가하는 것을 권장합니다.

마지막으로 자체 점검 순서를 제공합니다. 모니터 옆에 붙여두셔도 좋습니다: 키가 환경 변수에 있는지 확인, models 엔드포인트 연결 확인, 요청 본문이 유효한 JSON인지 확인, 모델이 uncensored인지 확인, max_tokens가 충분한지 확인, 응답의 finish_reason이 stop인지 length인지 확인, usage가 기록되었는지 확인. 일곱 항목 모두 정상일 때 연동이 완료된 것입니다.

자주 묻는 질문

공식 SDK를 반드시 사용해야 하나요?

필요 없습니다. 이는 표준 HTTPS POST 및 JSON이며, HTTP 요청을 보낼 수 있는 모든 언어에서 사용할 수 있습니다. SDK는 단순히 이를 감싸는 역할만 합니다.

model 필드에 무엇을 입력해야 하나요?

고정적으로 uncensored를 입력하십시오. 현재 이 모델만 제공되며, GET /v1/models를 통해 확인할 수 있습니다.

무료 체험 크레딧이 소진되면 어떻게 되나요?

요청이 402 오류를 반환하며 오류 코드는 no_credit입니다. 선불 크레딧을 충전하면 계속 사용할 수 있으며, 잔액은 만료되지 않으며 구독도 없습니다.

API 키를 재생성하면 기존 키에 영향을 미치나요?

영향을 미칩니다. 기존 키는 즉시 무효화되므로, 먼저 서비스에서 새 키로 교체한 후 재생성을 클릭하거나 짧은 중단 시간을 감수해야 합니다.

양식을 작성하면 API 키를 받을 수 있습니다

계정을 생성하고 키를 복사한 후 Base URL을 수정하십시오. 설정은 매우 간단합니다.