Skip to content

调用说明

本站点大部分模型都可以直接通过OpenAI的 API 进行调用, 您只需要更改模型名称即可。

OpenAI 调用

将 OpenAI 的 API 基础地址https://api.openai.com改为 UniAPI 的接口地址:https://api.uniapi.io,参照 OpenAI 官方文档搭配令牌页面生成的 Key 进行调用即可快速调用。

Python 示例

bash
pip install openai
python
from openai import OpenAI
client = OpenAI(
    base_url="https://api.uniapi.io/v1",
    api_key="sk-xxxxxx"
)

completion = client.chat.completions.create(
    model="gpt-4o-mini",
    max_tokens=16384,
    messages=[
        {"role": "user", "content": "hi"}
    ]
)
print(completion)

Curl 示例

聊天接口

bash
curl --request POST \
    --url https://api.uniapi.io/v1/chat/completions \
    --header 'Authorization: Bearer sk-替换为你的key' \
    -H "Content-Type: application/json" \
    --data '{
      "max_tokens": 1200,
      "model": "gpt-3.5-turbo",
      "temperature": 0.8,
      "top_p": 1,
      "presence_penalty": 1,
      "messages": [
          {
              "role": "system",
              "content": "You are ChatGPT, a large language model trained by OpenAI. Answer as concisely as possible."
          },
          {
              "role": "user",
              "content": "hi~"
          }
      ]
  }'

DALL-E

bash
curl  https://api.uniapi.io/v1/images/generations \
    -H 'Authorization: Bearer sk-替换为你的key' \
    -H "Content-Type: application/json" \
    -d '{
      "model": "dall-e-3",
      "prompt": "a white siamese cat",
      "n": 1,
      "size": "1024x1024"
    }'

vision

bash
curl  https://api.uniapi.io/v1/chat/completions \
    -H 'Authorization: Bearer sk-替换为你的key' \
    -H "Content-Type: application/json" \
    -d '{
      "max_tokens": 1200,
      "model": "gpt-4-vision-preview",
      "messages": [
          {
              "role": "system",
              "content": "You are an expert Tailwind developer"
          },
          {
              "role": "user",
              "content": [
                  {
                      "type": "text",
                      "text": "将图片生成网页代码"
                  },
                  {
                      "type": "image_url",
                      "image_url": {
                          "url": "data:image/jpeg;base64,xxxx=图片链接或者图片base64"
                      }
                  }
              ]
          }
      ]
  }'

whisper

bash
curl --request POST \
    --url https://api.uniapi.io/v1/audio/transcriptions \
    --header 'Authorization: Bearer sk-你的key' \
    --header 'Content-Type: multipart/form-data' \
    --form file=@/path/to/file/openai.mp3 \
    --form model=whisper-1

tts

bash
 curl https://api.uniapi.io/v1/audio/speech \
    -H "Authorization: Bearer sk-你的key" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "tts-1",
      "input": "你说点什么 包括中文!",
      "voice": "alloy"
    }' \
    --output speech.mp3

Claude

您使用OpenAI SDK或者使用OpenAI API格式,您只需要将model改成Claude的模型名称即可调用Claude的模型。

如果需要使用claudeAPI, 请在 base_url 中添加/claude后缀,例如:https://api.uniapi.io/claude

python 示例

bash
pip install anthropic
python
import anthropic

client = Anthropic(
    api_key="sk-xxxxxxx",
    base_url="https://api.uniapi.io/claude",
)
message = client.messages.create(
    model="claude-3-5-sonnet-20240620",
    max_tokens=1024,
    messages=[
        {"role": "user", "content": "Hello, Claude"}
    ]
)
print(message.content)

Curl 示例

更多示例,请查看Anthropic 官方文档

聊天接口

bash
curl --request POST \
    --url https://api.uniapi.io/claude/v1/messages \
    -H "Content-Type: application/json" \
    -H "x-api-key: sk-替换为你的key" \
    --data '{
  "model": "claude-3-haiku-20240307",
  "max_tokens": 1024,
  "messages": [
    {
      "role": "user",
      "content": "Hello, world"
    }
  ]
}'

Gemini

使用OpenAI SDK或者使用OpenAI API格式,您只需要将model改成Gemini的模型名称即可调用Gemini的模型。

Midjourney

  • 支持 midjourney-proxy-plus 接口协议, 接口地址使用:https://hk.uniapi.io(境内网路)或https://api.uniapi.io(境外网路)

  • Relax 模式路径:/mj-relax/mj Fast 模式路径:/mj/mj-fast/mj Turbo 模式路径:/mj-turbo/mj

详见接口说明

python 示例

python
import requests
import time
import json

# 配置信息
# Relax模式请求路径:/mj-relax
# Fast模式请求路径:/mj-fast
# Turbo模式请求路径:/mj-turbo
# 如果不填写,默认是Fast模式
BASE_URL = "https://api.uniapi.io/mj-relax"
BEARER_TOKEN = "your_token_here"
HEADERS = {
    "mj-api-secret:": f"{BEARER_TOKEN}",
    "Content-Type": "application/json"
}

class MJImageGenerator:
    def __init__(self):
        self.base_url = BASE_URL
        self.headers = HEADERS

    def submit_task(self, prompt):
        """提交图片生成任务"""
        url = f"{self.base_url}/mj/submit/imagine"
        payload = {
            "base64Array": [], # 这个是可选的,如果垫图,需要传入垫图的base64, 可以使用多张垫图 最多5张, 单张图片不超过1M
            "prompt": prompt, # 这个是必填的,prompt 是必填的
            "botType": "MID_JOURNEY" # 这个是必填的,botType 是必填的,MID_JOURNEY 表示 Midjourney 模型,NIJI_JOURNEY 表示 Niji 模型, 详细参考 https://docs.midjourney.com/docs/models
        }

        response = requests.post(url, headers=self.headers, json=payload)
        data = response.json()

        if data["code"] not in [1, 22]:
            raise Exception(f"提交任务失败: {data['description']}")

        return data["result"]
    def action(self, customId, taskId):
        """执行操作"""
        url = f"{self.base_url}/mj/submit/action"
        payload = {
            "customId": customId,
            "taskId": taskId
        }
        response = requests.post(url, headers=self.headers, json=payload)
        data = response.json()

        if data["code"] not in [1, 22]:
            raise Exception(f"提交任务失败: {data['description']}")

        return data["result"]
    def modal(self, taskId, prompt):
        """执行modal操作"""
        url = f"{self.base_url}/mj/submit/modal"
        payload = {
            "prompt": prompt,
            "taskId": taskId
        }
        response = requests.post(url, headers=self.headers, json=payload)
        data = response.json()

        if data["code"] not in [1, 22]:
            raise Exception(f"提交任务失败: {data['description']}")

        return data["result"]
    def describe(self, base64, botType):
        """执行图生文操作"""
        url = f"{self.base_url}/mj/submit/describe"
        payload = {
            "base64": base64,
            "botType": botType
        }
        response = requests.post(url, headers=self.headers, json=payload)
        data = response.json()

        if data["code"] not in [1, 22]:
            raise Exception(f"提交任务失败: {data['description']}")

        return data["result"]
    def shorten(self, prompt, botType):
        """执行缩短提示词的操作"""
        url = f"{self.base_url}/mj/submit/shorten"
        payload = {
            "prompt": prompt,
            "botType": botType
        }
        response = requests.post(url, headers=self.headers, json=payload)
        data = response.json()

        if data["code"] not in [1, 22]:
            raise Exception(f"提交任务失败: {data['description']}")

        return data["result"]

    def fetch_task_status(self, task_id):
        """获取任务状态"""
        url = f"{self.base_url}/mj/task/{task_id}/fetch"
        response = requests.get(url, headers=self.headers)
        return response.json()

    def wait_for_completion(self, task_id):
        """轮询等待任务完成"""
        while True:
            data = self.fetch_task_status(task_id)
            status = data["status"]
            progress = data["progress"]
            print(f"当前进度: {progress}")

            if status == "SUCCESS":
                print("任务完成!")
                print(f"图片链接: {data['imageUrl']}")
                print(f"提示词: {data['prompt']}")
                print(f"提示词EN: {data['promptEn']}")
                print("\n可用的操作按钮:")
                print("\按钮说明, 顺序,从左往右,从上往下。 Ux:表示你想要操作哪张图片。 🔄 表示重新绘制。 Vx:表示你想要变化哪一张图片 ")
                # 参考
                # https://docs.midjourney.com/docs/midjourney-discord
                # https://docs.midjourney.com/docs/variations
                for button in data["buttons"]:
                    label = button['label'] if button['label'] != "" else button['emoji']
                    print(f"{label}: {button['customId']}")
                return data
            elif status == "FAILURE":
                raise Exception(f"任务失败: {data['failReason']}")

            time.sleep(10)  # 每10秒轮询一次

def main():
    try:
        generator = MJImageGenerator()

        # 示例prompt
        # Cyberpunk 风格, 可以不填,可选值: 賽博朋克: Cyberpunk,星際: Warframe,動漫: ACGN,日本漫畫: Japanese comics/manga,水墨畫風格: Ink Wash Painting Style,原創: Original,風景畫: landscape,插畫: illustration,漫畫: Manga,現代自然: modern organic,創世紀: Genesis,海報風格: posterstyle,超現實主義: surrealism,素描: sketch,寫實: realism,水彩畫: Watercolor painting,立體主義: Cubism,黑白: black and white,膠片攝影風格: fm photography,電影化: cinematic,清晰的面部特徵: dlear facial features
        # Wide view 宽视角, 可以不填, 可选值: 寬視角: Wide view,鳥瞰視角: Aerial view,頂視角: Top view,仰視角: Upview,正面視角: Front view,頭部特寫: Headshot,超廣角視角: Ultrawideshot,中景: Medium Shot(MS),遠景: Long Shot(LS),景深: depth offield(dof)
        # Face Shot (VCU) 人物特写, 可以不填, 可选值: 臉部特寫: Face Shot (VCU),大特寫: Big Close-Up(BCU),特寫: Close-Up(CU),腰部以上: Waist Shot(WS),膝蓋以上: KneeShot(KS),全身照: Full Length Shot(FLS),極遠景: Extra Long Shot(ELS)
        # Cold light 灯光, 可以不填,可选值: 冷光: Cold light,暖光: Warm light,硬光: hard lighting,戲劇性光線: Dramatic light,反射光: reflection light,薄霧: Misty foggy,自然光: Natural light,陽光: Sun light,情緒化: moody
        # 可爱的猫, 描述你想要生成的图片
        # --q 2 表示质量, 可选值: 0.25,0.5,1,2, 参考 https://docs.midjourney.com/docs/quality
        # --s 50 表示艺术程度,可选值: 0-1000,参考 https://docs.midjourney.com/docs/stylize
        # --v 6.1 表示版本, 可选值:1、2、3、4、5、5.0、5.1、5.2、6 和 6.1, 如果使用niji模型,则需要改为 --niji 版本号,  参考 https://docs.midjourney.com/docs/models
        # --ar 4:3 表示宽高比
        # 更多请参考 https://docs.midjourney.com/docs/parameter-list
        prompt = "Cyberpunk,Wide view,Face Shot (VCU),Cold light,可爱的猫 --q 2 --s 50 --v 6.1 --ar 4:3"

        print("提交任务中...")
        task_id = generator.submit_task(prompt)
        print(f"任务ID: {task_id}")

        print("等待任务完成...")
        generator.wait_for_completion(task_id)

        # 按钮操作, 每次有按钮,都按照这个操作执行。
        # action_id = generator.action("MJ::JOB::upsample::1::4f9c53b7-dc2a-441f-a7e0-e8b65dd2ce6d", task_id)
        # print("等待任务完成...")
        # generator.wait_for_completion(action_id)

        # ------------------------------------------------------------

        #  特殊操作, CustomZoom, 先 执行 按钮操作, 然后 执行 modal 操作
        # 执行按钮操作
        # action_id = generator.action("MJ::CustomZoom::ec92d09b-e6c4-458c-952f-d34e87b090a8", task_id)
        # 执行 modal 操作
        # 填写变焦值, 例如 1.8
        # prompt += " --zoom 1.8"
        # modal_id = generator.modal(prompt, action_id)
        # print("等待任务完成...")
        # generator.wait_for_completion(modal_id)


        # 执行图生文操作
        # task_id = generator.describe("data:image/jpeg;base64,xxxxx", "MID_JOURNEY")
        # print(f"任务ID: {task_id}")

        # print("等待任务完成...")
        # generator.wait_for_completion(task_id)

        # 执行缩短提示词操作
        # task_id = generator.shorten("Please create a whimsical majestic tower of donuts, intricately crafted and adorned with a mesmerizing array of colorful sprinkles. Bring this sugary masterpiece to life, ensuring every detail is rendered in stunning magical realism. Thank you!", "MID_JOURNEY")
        # print(f"任务ID: {task_id}")

        # print("等待任务完成...")
        # generator.wait_for_completion(task_id)



    except Exception as e:
        print(f"发生错误: {str(e)}")

if __name__ == "__main__":
    main()

Suno

Python 示例

python
import requests
import time
from typing import Dict, Any

key = "sk-xxxxx"  # 替换为你的key
BASE_URL = "https://api.uniapi.io/suno"


def get_headers() -> Dict[str, str]:
    return {
        "Authorization": f"Bearer {key}",
        "Content-Type": "application/json"
    }

def handle_response(response: requests.Response) -> Dict[str, Any]:
    response_data = response.json()
    if response.status_code != 200:
        raise Exception(f"请求失败,状态码: {response.status_code},响应信息: {response_data}")
    if response_data.get("code") != "success":
        raise Exception(f"操作失败,响应信息: {response_data}")
    return response_data["data"]

def submit_lyrics(prompt: str) -> str:
    url = f"{BASE_URL}/submit/lyrics"
    data = {"prompt": prompt}
    response = requests.post(url, headers=get_headers(), json=data)
    return handle_response(response)

def fetch(task_id: str) -> Dict[str, Any]:
    url = f"{BASE_URL}/fetch/{task_id}"
    response = requests.get(url, headers=get_headers())
    return handle_response(response)

def submit_song(payload: Dict[str, Any]) -> str:
    url = f"{BASE_URL}/submit/music"
    response = requests.post(url, headers=get_headers(), json=payload)
    return handle_response(response)


def main():
    prompt = "愉快的,摇滚的,学猫叫"
    try:
        lyrics_task_id = submit_lyrics(prompt)
        lyrics_text = ""

        while True:
            lyrics_fetch = fetch(lyrics_task_id)
            task_status = lyrics_fetch["status"]
            if task_status == "FAILURE":
                raise Exception("歌词生成失败")
            if task_status == "SUCCESS":
                lyrics_text = lyrics_fetch['data']['text']
                break
            print(f"歌词生成状态: {task_status},请等待2s...")
            time.sleep(2)

        print("歌词内容:" + lyrics_text)

        if not lyrics_text:
            raise Exception("歌词为空终止调用")

        # 组装歌曲生成请求
        payload = {
            "prompt": lyrics_text,
            "tags": "emotional punk",
            "mv": "chirp-v3-5",
            "title": "学猫叫"
        }

        # 提交歌曲生成请求
        song_task_id = submit_song(payload)
        print("歌曲任务ID:" + song_task_id)

        isStream = False
        # 轮询查询歌曲生成状态
        while True:
            task_data = fetch(song_task_id)
            task_status = task_data["status"]

            if task_status == "FAILURE":
                raise Exception("歌曲生成失败")

            if task_status == "SUCCESS":
                break

            if task_status == "IN_PROGRESS" and isStream == False:
                isStream = True
                print(f"歌曲已经可以通过流播放,但不可下载")
                for song in task_data["data"]:
                    print(f"歌曲名称: {song['title']}")
                    print(f"歌曲封面: {song['image_url']}")
                    print(f"音频地址: {song['audio_url']}")
                    print("-" * 40)

            print(f"歌曲生成状态: {task_status},请等待15s...")

            time.sleep(15)
        # 打印歌曲信息
        for song in task_data["data"]:
            print(f"歌曲名称: {song['title']}")
            print(f"歌曲封面: {song['image_url']}")
            print(f"音频地址: {song['audio_url']}")
            print(f"视频地址: {song['video_url']}")
            print("-" * 40)

    except Exception as e:
        print(f"发生错误: {e}")

if __name__ == "__main__":
    main()

Udio

Python 示例

python
import requests
import time
from typing import Dict, Any

key = "sk-xxxxx"  # 替换为你的key
BASE_URL = "https://api.uniapi.io/udio"


def get_headers() -> Dict[str, str]:
    return {
        "Authorization": f"Bearer {key}",
        "Content-Type": "application/json"
    }

def handle_response(response: requests.Response) -> Dict[str, Any]:
    response_data = response.json()
    if response.status_code != 200:
        raise Exception(f"请求失败,状态码: {response.status_code},响应信息: {response_data}")
    if response_data.get("code") != "success":
        raise Exception(f"操作失败,响应信息: {response_data}")
    return response_data["data"]

def fetch(task_id: str) -> Dict[str, Any]:
    url = f"{BASE_URL}/fetch/{task_id}"
    response = requests.get(url, headers=get_headers())
    return handle_response(response)

def submit_song(payload: Dict[str, Any]) -> str:
    url = f"{BASE_URL}/submit/music"
    response = requests.post(url, headers=get_headers(), json=payload)
    return handle_response(response)


def main():
    try:
        # 组装歌曲生成请求
        # 自定义歌词示例:
        payload = {
            "gen_params": {
                "lyrics": "[Verse]\n城中古庙尘封梦乡\n梵蒂冈街头雾漫黄昏光\n信徒静踏圣殿的星芒\n祈求灵感心中起波浪\n\n[Verse 2]\n香火缭绕心愿飞扬\n青石阶边影子偷偷藏\n钟声长鸣驱散迷茫\n老君庙中祷告声悠长\n\n[Chorus]\n去梵蒂冈上一柱老君庙请的香\n滚滚红尘中找寻方向\n去追梦像是风一样轻荡\n心灵在这里找到新希望\n\n[Verse 3]\n巷弄深处古老神像\n祈愿的心灵火焰炙热燃\n古文明与现代相辉映\n圣光普照人间暖心肠\n\n[Bridge]\n万里之外的梦想启航\n老君庙中眺望远方\n香火明灭如星光闪\n心愿在心中永存不忘\n\n[Chorus]\n去梵蒂冈上一柱老君庙请的香\n滚滚红尘中找寻方向\n去追梦像是风一样轻荡\n心灵在这里找到新希望",
                # user 使用用户提供的歌词生成音乐,此时 prompt 的作用类似于 tags,填写风格
                # instrumental 用于创建纯音乐,prompt 用于相关提示词
                # generate 表示自动生成歌词,prompt 用于描述需要生成什么样的歌曲。
                "lyrics_type": "user",
                "prompt": "周杰伦",
                "bypass_prompt_optimization": False,
                "seed": -1,
                # 用于指定在完整歌曲中生成片段的起始和结束位置。0% (0) 对应歌曲开头,50% (0.5) 对应歌曲中间,100% (1) 对应歌曲结尾。点击数值指示器可切换为自动模式,让模型自行决定最佳位置。这个功能在使用歌曲扩展特性时特别有用。
	            # 歌曲片段开始位置	范围 0-1, 默认 0
                "song_section_start": 0.4,
                # 控制提示词对生成内容的影响程度。较高的值可以提高对提示词的遵循度,但可能会导致生成的声音不够自然。
                # 提示词强度	范围 0-1, 默认 0.5
                "prompt_strength": 0.5,
                # 控制模型在生成音频时对清晰度和乐器分离度的优先级。较高的值可能会产生更清晰的音频,但声音可能不够自然。
                # 清晰度强度	范围 0-1,默认 0.25
                "clarity_strength": 0.25,
                # 控制歌词对生成内容的影响程度。较低的值可能会产生更自然的声音,但可能会忽略部分歌词内容。
                # 歌词强度	范围 0-1,默认 0.5
                "lyrics_strength": 0.5,
                # 实验性功能。用于在生成质量和生成速度之间进行权衡。
                # 生成质量	可选 0.25, 0.5, 0.75, 1。默认 0.75,数字越大,质量越高,速度越慢。
                "generation_quality": 0.75,
                "model_type": "udio130-v1.5", # udio32-v1.5 (30s的歌曲) / udio130-v1.5 (130s的歌曲)
                "config": {
                    "mode": "regular" # 生成歌曲
                }
            }
        }

        # 自动生成歌词示例
        payload2 = {
            "gen_params": {
                "prompt": "愉快的,摇滚的,学猫叫",
                "lyrics": "",
                "lyrics_type": "generate",
                "bypass_prompt_optimization": False,
                "seed": -1,
                "song_section_start": 0.4,
                "prompt_strength": 0.5,
                "clarity_strength": 0.25,
                "lyrics_strength": 0.5,
                "generation_quality": 0.75,
                "model_type": "udio130-v1.5",
                "config": {
                    "mode": "regular"
                }
            }
        }

        # 提交歌曲生成请求
        song_task_id = submit_song(payload)
        print("歌曲任务ID:" + song_task_id)

        isStream = False
        # 轮询查询歌曲生成状态
        while True:
            task_data = fetch(song_task_id)
            task_status = task_data["status"]

            if task_status == "FAILURE":
                raise Exception("歌曲生成失败")

            if task_status == "SUCCESS":
                break

            print(f"歌曲生成状态: {task_status},请等待15s...")

            time.sleep(15)
        # 打印歌曲信息
        for song in task_data["data"]['songs']:
            print(f"歌曲名称: {song['title']}")
            print(f"歌曲封面: {song['image_path']}")
            print(f"音频地址: {song['song_path']}")
            print("-" * 40)

    except Exception as e:
        print(f"发生错误: {e}")

if __name__ == "__main__":
    main()