คอนโซล

การอ้างอิง API

ข้อตกลงทั่วไป

URL ฐาน

จุดเชื่อมต่อทั้งหมดให้บริการภายใต้คำนำหน้า /v1

การรับรองความถูกต้อง

การเรียกจุดเชื่อมต่อ /v1/* ใช้การรับรองความถูกต้อง คีย์ API (ไม่ใช่ JWT) คีย์ API ส่งผ่านส่วนหัวต่อไปนี้:

ส่วนหัวรูปแบบคำอธิบาย
AuthorizationBearer <api_key>สไตล์ OpenAI จุดเชื่อมต่อที่เข้ากันได้กับ Anthropic ยังยอมรับ x-api-key กับ anthropic-version: 2023-06-01

คีย์ที่ขาดหายไปหรือไม่ถูกต้องจะส่งกลับ 401

การตรวจสอบยอดคงเหลือล่วงหน้า

จุดเชื่อมต่อเรียกโมเดลทั้งหมดจะตรวจสอบยอดคงเหลือก่อนการดำเนินการ:

  • ยอดคงเหลือไม่เพียงพอจะส่งกลับ Insufficient credit, แมปเป็น:
    • พิธีสาร OpenAI: HTTP 400, code = insufficient_quota
    • พิธีสาร Anthropic: HTTP 402, type = billing_error
  • จุดเชื่อมต่อบางรายการยังประเมินต้นทุนขั้นต่ำต่อโมเดลสำหรับการตรวจสอบล่วงหน้าครั้งที่สอง

Create Chat CompletionPOSThttps://api.basicrouter.ai/api/v1/chat/completions

จุดเชื่อมต่อที่เข้ากันได้กับ OpenAI Chat Completions รองรับการสตรีมและไม่สตรีม การเรียก เครื่องมือ โหมด JSON และอินพุตหลายรูปแบบ

ฟิลด์ประเภทจำเป็นคำอธิบาย
modelStringใช่ชื่อโมเดล
messagesMessage[]ใช่ข้อความสนทนา
streamBooleanไม่โหมดสตรีม ค่าเริ่มต้น false
temperatureDoubleไม่อุณหภูมิการสุ่มตัวอย่าง
max_tokensIntegerไม่โทเค็นเอาต์พุตสูงสุด
top_pDoubleไม่การสุ่มตัวอย่างนิวเคลียส
presence_penaltyDoubleไม่—
frequency_penaltyDoubleไม่—
toolsTool[]ไม่นิยามเครื่องมือ
tool_choiceString|Objectไม่auto / none / required / ระบุฟังก์ชันเฉพาะ
response_formatObjectไม่{type, json_schema:{name,schema,strict}}; text/json_object/json_schema.
parallel_tool_callsBooleanไม่—
metadataMapไม่ข้อมูลเมตาแบบส่งผ่าน

ฟิลด์ของ Message:

ฟิลด์ประเภทคำอธิบาย
roleStringsystem / user / assistant / tool.
contentString|Arrayข้อความธรรมดาหรืออาร์เรย์ของบล็อกเนื้อหาหลายรูปแบบ ([{type:"text",text},{type:"image_url",image_url:{url}}])
tool_call_idStringเชื่อมโยงไปยัง tool_calls เมื่อ role=tool
tool_callsToolCall[]มีเมื่อ role=assistant เรียกเครื่องมือ
ฟิลด์ประเภทคำอธิบาย
typeStringค่าคงที่ function
functionObjectนิยามฟังก์ชัน
function.nameStringชื่อฟังก์ชัน
function.descriptionStringคำอธิบายฟังก์ชัน
function.parametersObjectJSON Schema สำหรับอินพุต
curl --request POST \
  --url https://api.basicrouter.ai/api/v1/chat/completions \
  --header "Authorization: Bearer $BASICROUTER_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "model": "glm-5.2",
    "messages": [{"role": "user", "content": "Describe Hangzhou in one sentence."}],
    "stream": false,
    "temperature": 0.7
  }'
{
  "id": "chatcmpl-xxx",
  "object": "chat.completion",
  "created": 1721380000,
  "model": "glm-5.2",
  "choices": [
    {
      "index": 0,
      "message": {"role": "assistant", "content": "Hangzhou is ..."},
      "finish_reason": "stop"
    }
  ],
  "usage": {"prompt_tokens": 12, "completion_tokens": 18, "total_tokens": 30}
}

ฟิลด์การตอบกลับ (ไม่สตรีม):

ฟิลด์ประเภทคำอธิบาย
idStringรหัสการเติมเต็ม
objectStringค่าคงที่ chat.completion
createdLongการประทับเวลาที่สร้าง (วินาที)
modelStringชื่อโมเดล
choicesChoice[]{index, message:{role, content, tool_calls?}, finish_reason}.
usageObject{prompt_tokens, completion_tokens, total_tokens}.
ฟิลด์ประเภทคำอธิบาย
idStringรหัสการเรียกเครื่องมือ
typeStringค่าคงที่ function
functionObjectรายละเอียดการเรียกฟังก์ชัน
function.nameStringชื่อฟังก์ชัน
function.argumentsObjectอาร์กิวเมนต์ฟังก์ชัน

ตัวอย่างการตอบกลับแบบสตรีม:

data: {"object":"chat.completion.chunk","choices":[{"delta":{"role":"assistant","content":"..."}}]}

data: {"object":"chat.completion.chunk","choices":[{"delta":{"content":"..."}}]}

data: [DONE]

Create ResponsePOSThttps://api.basicrouter.ai/api/v1/responses

จุดเชื่อมต่อที่เข้ากันได้กับ OpenAI Responses ใช้ input แทน messages instructions แทนข้อความระบบ และ บล็อก text แทน response_format

ฟิลด์ประเภทจำเป็นคำอธิบาย
modelStringใช่ชื่อโมเดล
inputString|Arrayใช่สตริงธรรมดา (ข้อความผู้ใช้) หรืออาร์เรย์ออบเจ็กต์ข้อความ
instructionsStringไม่พร้อมต์ระบบ
streamBooleanไม่ค่าเริ่มต้น false
max_output_tokensIntegerไม่โทเค็นเอาต์พุตสูงสุด
temperatureDoubleไม่ค่าเริ่มต้น 1
top_pDoubleไม่—
toolsTool[]ไม่ระดับบน {type, name, description, parameters}
tool_choiceString|Objectไม่auto/none/required/{type,name}.
textObjectไม่{format:{type, name, schema, strict}}; text/json_object/json_schema.
metadataMapไม่—
previous_response_idStringไม่รหัสการตอบกลับก่อนหน้าสำหรับหลายรอบ
parallel_tool_callsBooleanไม่—
curl --request POST \
  --url https://api.basicrouter.ai/api/v1/responses \
  --header "Authorization: Bearer $BASICROUTER_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "model": "glm-5.2",
    "input": "Describe Hangzhou in one sentence.",
    "instructions": "Be concise.",
    "stream": false
  }'
{
  "id": "resp_xxx",
  "object": "response",
  "model": "glm-5.2",
  "status": "completed",
  "created_at": 1721380000,
  "output": [
    {
      "id": "msg_xxx",
      "type": "message",
      "role": "assistant",
      "content": [{"type": "output_text", "text": "Hangzhou is ..."}],
      "status": "completed"
    }
  ],
  "usage": {"input_tokens": 12, "output_tokens": 18, "total_tokens": 30}
}

ฟิลด์การตอบกลับ (ไม่สตรีม):

ฟิลด์ประเภทคำอธิบาย
idStringรหัสการตอบกลับ
objectStringค่าคงที่ response
modelStringชื่อโมเดล
statusStringเช่น completed
created_atLongการประทับเวลาที่สร้าง (วินาที)
outputArrayรายการเอาต์พุต รายการข้อความ: {id, type:"message", role, content:[{type:"output_text", text}], status} รายการเรียกเครื่องมือ: {type:"function_call", id, name, call_id, arguments, status}
usageObject{input_tokens, output_tokens, total_tokens} สำหรับโมเดล Claude input_tokens รวม cache_read และ output_tokens รวม cache_write

การสตรีมตามเหตุการณ์ API Responses:

เหตุการณ์คำอธิบาย
response.createdจุดเริ่มต้นของสตรีมการตอบกลับ
response.output_text.deltaการอัปเดตเอาต์พุตข้อความแบบเพิ่มขึ้น
response.completedจุดสิ้นสุดของสตรีมการตอบกลับ

Create Anthropic MessagePOSThttps://api.basicrouter.ai/api/v1/messages

จุดเชื่อมต่อที่เข้ากันได้กับ Anthropic Messages ยอมรับส่วนหัว x-api-key และ anthropic-version: 2023-06-01 บล็อกเนื้อหารองรับ text, image, tool_use, tool_result, thinking และ redacted_thinking

ฟิลด์ประเภทจำเป็นฟิลด์ JSONคำอธิบาย
modelStringใช่modelชื่อโมเดล
messagesMessage[]ใช่messagesข้อความสนทนา
systemString|Arrayไม่systemพร้อมต์ระบบ สตริงหรือ [{type,text}]
maxTokensIntegerใช่max_tokensโทเค็นเอาต์พุตสูงสุด
streamBooleanไม่streamการสตรีม
temperatureDoubleไม่temperature—
topPDoubleไม่top_p—
topKIntegerไม่top_k—
toolsTool[]ไม่toolsนิยามเครื่องมือ (input_schema)
toolChoiceObjectไม่tool_choice—
metadataMapไม่metadata—
thinkingObjectไม่thinkingการกำหนดค่าการคิดแบบขยาย
stopSequencesObjectไม่stop_sequences—
anthropicBetaObjectไม่anthropic_betaส่วนหัวฟีเจอร์เบต้า
ฟิลด์ประเภทคำอธิบาย
roleStringบทบาทข้อความ เช่น user / assistant
contentString|ContentBlock[]ข้อความธรรมดาหรืออาร์เรย์ของบล็อกเนื้อหา
ฟิลด์ประเภทคำอธิบาย
typeStringหนึ่งใน text, image, tool_use, tool_result, thinking, redacted_thinking
textStringมีเมื่อ type เป็น text
sourceObjectมีเมื่อ type เป็น image

ตัวอย่างบล็อกภาพ:

{ "type": "image", "source": { "type": "base64", "media_type": "...", "data": "..." } }
{ "type": "image", "source": { "type": "url", "url": "..." } }
ฟิลด์ประเภทคำอธิบาย
nameStringชื่อฟังก์ชัน
descriptionStringคำอธิบายฟังก์ชัน
input_schemaObjectJSON Schema สำหรับอินพุต
cache_controlObjectการควบคุมแคชที่เลือกได้
curl --request POST \
  --url https://api.basicrouter.ai/api/v1/messages \
  --header "Authorization: Bearer $BASICROUTER_API_KEY" \
  --header "anthropic-version: 2023-06-01" \
  --header "Content-Type: application/json" \
  --data '{
    "model": "claude-sonnet-4.6",
    "max_tokens": 1024,
    "messages": [{"role": "user", "content": "Describe Hangzhou in one sentence."}]
  }'
{
  "id": "msg_xxx",
  "type": "message",
  "role": "assistant",
  "model": "claude-sonnet-4.6",
  "content": [{"type": "text", "text": "Hangzhou is ..."}],
  "stop_reason": "end_turn",
  "usage": {"input_tokens": 12, "output_tokens": 18}
}

ฟิลด์การตอบกลับ (ไม่สตรีม):

ฟิลด์ประเภทคำอธิบาย
idStringรหัสข้อความ
typeStringค่าคงที่ message
roleStringค่าคงที่ assistant
modelStringชื่อโมเดล
contentContentBlock[]บล็อกเนื้อหาของการตอบกลับ (เช่น {type:"text", text}, {type:"tool_use", ...})
stop_reasonStringเช่น end_turn, tool_use, max_tokens
usageObject{input_tokens, output_tokens}
เหตุการณ์คำอธิบาย
message_startจุดเริ่มต้นของสตรีมข้อความ
content_block_startจุดเริ่มต้นของบล็อกเนื้อหาใหม่
content_block_deltaการอัปเดตแบบเพิ่มขึ้นสำหรับบล็อกเนื้อหา
content_block_stopจุดสิ้นสุดของบล็อกเนื้อหา
message_deltaการอัปเดตแบบเพิ่มขึ้นสำหรับข้อความ
message_stopจุดสิ้นสุดของสตรีมข้อความ

List ModelsGEThttps://api.basicrouter.ai/api/v1/models

ส่งคืนโมเดล API ที่ออนไลน์และเปิดใช้งานทั้งหมด

curl --request GET \
  --url https://api.basicrouter.ai/api/v1/models \
  --header "Authorization: Bearer $BASICROUTER_API_KEY"
{
  "object": "list",
  "data": [
    {
      "id": "glm-5.2",
      "object": "model",
      "display_name": "glm-5.2",
      "created": 1721380000,
      "owned_by": "Zai",
      "input_modalities": ["text", "image"],
      "output_modalities": ["text"],
      "context_length": 128000,
      "description": "..."
    }
  ]
}

ฟิลด์ของแต่ละรายการโมเดล (data[]):

ฟิลด์ประเภทคำอธิบาย
idStringรหัสโมเดล
objectStringค่าคงที่ model
display_nameStringชื่อที่แสดง
createdLongการประทับเวลาที่สร้าง (วินาที)
owned_byStringเจ้าของ / ผู้ผลิต
input_modalitiesString[]เช่น ["text","image"]
output_modalitiesString[]เช่น ["text"]
context_lengthIntegerความยาวบริบทสูงสุด
descriptionStringคำอธิบายโมเดล

Retrieve ModelGEThttps://api.basicrouter.ai/api/v1/models/{model}

ส่งคืนโมเดลเดียวที่มีรูปร่างเดียวกับรายการในรายการ ส่งกลับ HTTP 404 เมื่อ โมเดลไม่มีอยู่

curl --request GET \
  --url https://api.basicrouter.ai/api/v1/models/gpt-5.5 \
  --header "Authorization: Bearer $BASICROUTER_API_KEY"

การตอบกลับสำเร็จ: ออบเจ็กต์โมเดลเดียวที่มีฟิลด์เดียวกันกับ รายการใน /v1/models

เมื่อโมเดลไม่มีอยู่ จะส่งกลับ HTTP 404:

{"error": {"message": "The model 'xxx' does not exist", "type": "invalid_request_error", "code": "invalid_model_error"}}

List Image ModelsGEThttps://api.basicrouter.ai/api/v1/image-models

สอบถามความละเอียด อัตราส่วน และจำนวนสูงสุดที่รองรับโดยโมเดลภาพก่อน เรียก /v1/image-generations ไม่ต้องรับรองความถูกต้อง

ฟิลด์ประเภทคำอธิบาย
idStringรหัสโมเดล
objectStringค่าคงที่ image_model
displayNameStringชื่อที่แสดง
descriptionStringคำอธิบายโมเดล
iconStringURL ไอคอน
createdLongการประทับเวลาที่สร้าง (วินาที)
maxCountIntegerภาพสูงสุดต่อคำขอ
fileMaxIntegerภาพอ้างอิงสูงสุด เมื่อเป็น 0 จะไม่รองรับการสร้างภาพจากภาพ
resolutionsString[]ความละเอียดที่รองรับ เช่น ["720p","1080p"]
ratiosString[]อัตราส่วนภาพที่รองรับ เช่น ["1:1","3:2"]
curl --request GET \
  --url https://api.basicrouter.ai/api/v1/image-models \
  --header "Authorization: Bearer $BASICROUTER_API_KEY"
{
  "object": "list",
  "data": [
    {
      "id": "gpt-image-2",
      "object": "image_model",
      "displayName": "GPT Image 1",
      "description": "...",
      "icon": "...",
      "created": 1721380000,
      "maxCount": 4,
      "fileMax": 10,
      "resolutions": ["720p", "1080p"],
      "ratios": ["1:1", "3:2"]
    }
  ]
}

List Video ModelsGEThttps://api.basicrouter.ai/api/v1/video-models

สอบถามค่า videoType ที่รองรับ ช่วงระยะเวลา ความละเอียด และ อัตราส่วนสำหรับโมเดลวิดีโอก่อนเรียก /v1/video-generations ไม่ ต้องรับรองความถูกต้อง

ฟิลด์ประเภทคำอธิบาย
idStringรหัสโมเดล
objectStringค่าคงที่ video_model
displayNameStringชื่อที่แสดง
descriptionStringคำอธิบายโมเดล
iconStringURL ไอคอน
createdLongการประทับเวลาที่สร้าง (วินาที)
allowedVideoTypesVideoTypeOption[]รายการ videoType ที่รองรับ
videoDurationMinIntegerวินาทีขั้นต่ำต่อคลิป
videoDurationMaxIntegerวินาทีสูงสุดต่อคลิป
videoDurationSuggestInteger[]ขั้นระยะเวลาที่แนะนำ เช่น [5,8,10]
resolutionsString[]ความละเอียดที่รองรับ
ratiosString[]อัตราส่วนภาพที่รองรับ
resolutionOptionsResolutionOption[]ชุดค่าผสมความละเอียด+อัตราส่วน+ขนาดแบบโครงสร้าง
fileMaxIntegerเนื้อหาอ้างอิงสูงสุด

ฟิลด์ของ VideoTypeOption:

ฟิลด์ประเภทคำอธิบาย
codeIntegerค่า videoType ที่ต้องส่งไปยัง /v1/video-generations
nameStringชื่อประเภทที่แปลแล้ว (ข้อความเป็นวิดีโอ / ภาพเป็นวิดีโอ / ...)
curl --request GET \
  --url https://api.basicrouter.ai/api/v1/video-models \
  --header "Authorization: Bearer $BASICROUTER_API_KEY"
{
  "object": "list",
  "data": [
    {
      "id": "sora-2",
      "object": "video_model",
      "displayName": "Sora 2",
      "description": "...",
      "icon": "...",
      "created": 1721380000,
      "allowedVideoTypes": [
        {"code": 1, "name": "text-to-video"},
        {"code": 2, "name": "image-to-video"},
        {"code": 3, "name": "image-to-video (first/last frame)"}
      ],
      "videoDurationMin": 5,
      "videoDurationMax": 10,
      "videoDurationSuggest": [5, 8, 10],
      "resolutions": ["1080p", "720p"],
      "ratios": ["16:9", "9:16"],
      "fileMax": 5
    }
  ]
}

คำอธิบายฟิลด์ระดับราคา

4 endpoint สำหรับการคิวรีโมเดล /v1/models, /v1/models/{model}, /v1/image-models และ /v1/video-models จะคืนค่าราคาที่เรียกเก็บจริงสำหรับผู้เรียก (ผู้ใช้ API Key) ซึ่งตรงกับค่าใช้จ่ายจริง และคืนค่าระดับราคาทั้งหมดของโมเดลนั้น

ความแตกต่างของชื่อฟิลด์:/v1/models / /v1/models/{model} ใช้สไตล์ OpenAI snake_case (price_tiers); /v1/image-models / /v1/video-models ใช้ camelCase (priceTiers)โครงสร้างเหมือนกัน

price_tiers / priceTiers เป็น array โดยแต่ละ element คือระดับราคา:

ฟิลด์ประเภทคำอธิบาย
outputPricedecimalราคาต่อหน่วยเอาต์พุตที่มีผลสำหรับผู้เรียกปัจจุบัน
cachePricedecimalราคาแคช (โมเดลทั่วไป, ใช้สูตรการเรียกเก็บเงินแบบเก่า)
cacheReadPricedecimalราคาต่อหน่วยการอ่านแคช (เฉพาะ Bedrock Claude)
cacheWritePricedecimalราคาต่อหน่วยการเขียนแคช (เฉพาะ Bedrock Claude)
ratiodecimalอัตราคูณการเรียกเก็บเงิน โหมด FIXED คือ 1; โหมด RATIO คือ อัตราคูณของผู้ใช้/กลุ่ม
modestringโหมดราคา:RATIO / FIXED
planIdstringID แผนราคาที่ตรงกัน อาจเป็น null

โมเดลทั้งสามประเภทใช้โครงสร้างเดียวกัน ต่างกันที่การเติมฟิลด์คำอธิบายเท่านั้น ฟิลด์ที่ไม่เกี่ยวข้องเป็น null:

ประเภทโมเดลUNITฟิลด์คำอธิบายที่มีผล
ข้อความtokenregion / bandMin / bandMax
รูปภาพimageresolution / clarity
วิดีโอvideoresolution / clarity

ความหมายของราคา:ค่า inputPrice / outputPrice / cacheReadPrice / cacheWritePrice ที่คืนมา เป็นหน่วยราคาเรียกเก็บสุดท้ายสำหรับผู้ใช้ API Key ปัจจุบัน หลังจากแก้ไขผ่าน price chain (chain)→ guidance → ราคาฐาน ตรงกับค่าใช้จ่ายจริง หน่วยราคาที่ผู้เรียกเห็นจะแตกต่างกันตามกลุ่ม pricing chain (reseller / distributor / องค์กร / การตั้งค่าระดับผู้ใช้)

ยอดหักจริง = ปริมาณการใช้ ÷ quantity × ราคาต่อหน่วยที่เกี่ยวข้อง × ratio สำหรับวิดีโอที่คิดตามวินาที: ยอดหักจริง = duration × outputPrice × ratio

การจัดการขอบเขตและข้อยกเว้น (endpoint แบบอ่านอย่างเดียวจะไม่คืน 500 เนื่องจากปัญหาการตั้งค่าราคา)

สถานการณ์พฤติกรรม
การแก้ไขระดับราคาเดียวล้มเหลว (นโยบายราคาปฏิเสธการเข้าถึง, การตั้งค่าขาดหาย)ข้ามระดับนั้น บันทึก warn log แล้วแก้ไขระดับที่เหลือต่อ
ระดับราคาทั้งหมดของโมเดลแก้ไขไม่สำเร็จเป็น array ว่าง [] โมเดลยังคงคืนค่าปกติ
โมเดลไม่มีการตั้งค่าราคาใดๆเป็น array ว่าง []
การแก้ไขราคาเกิดข้อยกเว้นที่ไม่ได้จัดการtry-catch ทั้งหมด คืนค่า array ว่าง endpoint ยังคง 200

ตัวอย่างการตอบกลับ (/v1/models, โมเดลข้อความ):

{
  "object": "list",
  "data": [
    {
      "id": "gpt-4o",
      "object": "model",
      "display_name": "gpt-4o",
      "context_length": 128000,
      "price_tiers": [
        {
          "region": "GLOBAL",
          "bandMin": null,
          "bandMax": null,
          "resolution": null,
          "clarity": null,
          "unit": "token",
          "quantity": 1000,
          "description": "ต่อ 1,000 token",
          "inputPrice": 0.0025,
          "outputPrice": 0.01,
          "cachePrice": 0.00125,
          "cacheReadPrice": 0,
          "cacheWritePrice": 0,
          "ratio": 1,
          "mode": "RATIO",
          "planId": null
        }
      ]
    }
  ]
}

ตัวอย่างการตอบกลับ (/v1/image-models, โมเดลรูปภาพ, โครงสร้าง priceTiers เหมือนข้างต้น, unit คือ image):

{
  "object": "list",
  "data": [
    {
      "id": "dall-e-3",
      "object": "image_model",
      "displayName": "dall-e-3",
      "resolutions": ["1024x1024", "1792x1024", "1024x1792"],
      "priceTiers": [
        {
          "region": null,
          "bandMin": null,
          "bandMax": null,
          "resolution": "1024x1024",
          "clarity": "standard",
          "unit": "image",
          "quantity": 1,
          "description": "ต่อรูป",
          "inputPrice": 0,
          "outputPrice": 0.04,
          "cachePrice": 0,
          "cacheReadPrice": 0,
          "cacheWritePrice": 0,
          "ratio": 1,
          "mode": "RATIO",
          "planId": null
        }
      ]
    }
  ]
}

Create Image GenerationPOSThttps://api.basicrouter.ai/api/v1/image-generations

ส่งงานสร้างภาพแบบอะซิงโครนัส ส่งคืน taskId ทันที ดึงผลลัพธ์โดยโพล GET /v1/image-generations/{taskId} หรือผ่าน เว็บฮุก callbackUrl

model ค่า resolution / ratio ที่รองรับ ขีดจำกัดบน count และขีดจำกัดการอัปโหลดภาพอ้างอิง (fileMax) ต้องได้รับจาก GET /v1/image-models ก่อน ยอมรับเฉพาะค่า ที่ระบุในสเปกของโมเดลนั้นเท่านั้น

ฟิลด์ประเภทจำเป็นคำอธิบาย
textStringใช่พร้อมต์
modelStringใช่ชื่อโมเดล
imageUrlsString[]ไม่URL ภาพอ้างอิง (ภาพเป็นภาพ)
countIntegerไม่จำนวนภาพ (≥0)
resolutionStringไม่ความละเอียด (ดู /v1/image-models)
ratioStringไม่อัตราส่วนภาพ
callbackUrlStringไม่URL เว็บฮุกระดับงาน
curl --request POST \
  --url https://api.basicrouter.ai/api/v1/image-generations \
  --header "Authorization: Bearer $BASICROUTER_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "model": "seedream-4.5",
    "text": "A cat drinking water by the river",
    "count": 1,
    "resolution": "2k",
    "ratio": "1:1",
    "imageUrls": []
  }'
{
  "code": 200,
  "message": "image task is commit",
  "data": {"taskId": "img_xxx"}
}

การตอบกลับข้อผิดพลาด:

// Insufficient credit
{ "code": 500, "message": "Insufficient credit" }

// Model not found
{ "code": 404, "message": "Model not found: xxx" }

Retrieve Image GenerationGEThttps://api.basicrouter.ai/api/v1/image-generations/{taskId}

โพลงานสร้างภาพ status คือ pending / success / failed images เป็นอาร์เรย์ URL ของภาพที่แปลงเป็นสตริง JSON text มีคำอธิบายข้อความที่โมเดลแนบมา (เช่น เอาต์พุตหลายรูปแบบของ Gemini) หากไม่มีจะเป็น null

curl --request GET \
  --url https://api.basicrouter.ai/api/v1/image-generations/img_xxx \
  --header "Authorization: Bearer $BASICROUTER_API_KEY"
{
  "code": 200,
  "message": "success",
  "data": {
    "taskId": "img_xxx",
    "status": "success",
    "errorMessage": null,
    "images": "[\"https://.../1.png\"]",
    "text": null
  }
}

ฟิลด์ data การตอบกลับ:

ฟิลด์ประเภทคำอธิบาย
taskIdStringรหัสงาน
statusStringpending / success / failed.
errorMessageStringเหตุผลความล้มเหลว null เมื่อสำเร็จ
imagesStringสตริง JSON ของอาร์เรย์ URL ภาพ เช่น "[\"https://.../1.png\"]"
textStringคำอธิบายข้อความที่โมเดลแนบมา (เช่น เอาต์พุตหลายรูปแบบของ Gemini) มิฉะนั้นเป็น null

ไม่พบงาน:

{ "code": 500, "message": "task not found" }

หากระบุ callbackUrl ไว้ตอนส่ง เซิร์ฟเวอร์จะส่งผลลัพธ์ success / failed ขั้นสุดท้ายผ่านเว็บฮุกด้วยรูปแบบ data เดียวกัน

ตัวอย่างแบบเต็ม (ส่ง + โพล)

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 ImageGenerationExample {
  private static final String BASE = "https://api.basicrouter.ai/api/v1";
  private static final String API_KEY = System.getenv("BASICROUTER_API_KEY");

  public static void main(String[] args) throws Exception {
    HttpClient http = HttpClient.newBuilder()
        .connectTimeout(Duration.ofSeconds(10)).build();

    // 1. Submit the task.
    String body = "{"
        + "\"model\":\"seedream-4.5\","
        + "\"text\":\"A cat drinking water by the river\","
        + "\"count\":1,"
        + "\"resolution\":\"2k\","
        + "\"ratio\":\"1:1\","
        + "\"imageUrls\":[]"
        + "}";
    HttpResponse<String> submit = http.send(
        HttpRequest.newBuilder(URI.create(BASE + "/image-generations"))
            .header("Authorization", "Bearer " + API_KEY)
            .header("Content-Type", "application/json")
            .POST(HttpRequest.BodyPublishers.ofString(body)).build(),
        HttpResponse.BodyHandlers.ofString());

    String taskId = extract(submit.body(), "taskId");
    System.out.println("taskId = " + taskId);

    // 2. Poll until terminal status.
    String status = "pending";
    while ("pending".equals(status)) {
      Thread.sleep(15_000L);
      HttpResponse<String> poll = http.send(
          HttpRequest.newBuilder(URI.create(BASE + "/image-generations/" + taskId))
              .header("Authorization", "Bearer " + API_KEY).GET().build(),
          HttpResponse.BodyHandlers.ofString());
      status = extract(poll.body(), "status");
      System.out.println("status = " + status);
    }

    if (!"success".equals(status)) {
      throw new RuntimeException("image generation failed: " + status);
    }
    // images is a JSON-stringified array of URLs.
    String images = extract(pollResult(http, taskId), "images");
    System.out.println("images = " + images);
  }

  // Minimal JSON field extractor — use Jackson/Gson in production.
  private static String extract(String json, String field) {
    int i = json.indexOf("\"" + field + "\":");
    if (i < 0) return null;
    i += field.length() + 3;
    if (json.charAt(i) == '\"') {
      int end = json.indexOf('\"', i + 1);
      return json.substring(i + 1, end);
    }
    int end = i;
    while (end < json.length() && "0123456789.".indexOf(json.charAt(end)) >= 0) end++;
    return json.substring(i, end);
  }

  private static String pollResult(HttpClient http, String taskId) throws Exception {
    return http.send(HttpRequest.newBuilder(URI.create(BASE + "/image-generations/" + taskId))
        .header("Authorization", "Bearer " + API_KEY).GET().build(),
        HttpResponse.BodyHandlers.ofString()).body();
  }
}
import os
import time
import requests

BASE = "https://api.basicrouter.ai/api/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['BASICROUTER_API_KEY']}"}

# 1. Submit the task.
resp = requests.post(
    f"{BASE}/image-generations",
    headers={**HEADERS, "Content-Type": "application/json"},
    json={
        "model": "seedream-4.5",
        "text": "A cat drinking water by the river",
        "count": 1,
        "resolution": "2k",
        "ratio": "1:1",
        "imageUrls": [],
    },
)
resp.raise_for_status()
task_id = resp.json()["data"]["taskId"]
print(f"taskId = {task_id}")

# 2. Poll until terminal status.
while True:
    time.sleep(15)
    poll = requests.get(f"{BASE}/image-generations/{task_id}", headers=HEADERS)
    poll.raise_for_status()
    data = poll.json()["data"]
    status = data["status"]
    print(f"status = {status}")
    if status != "pending":
        break

if status != "success":
    raise RuntimeError(f"image generation failed: {data.get('errorMessage')}")

# images is a JSON-stringified array of URLs.
import json
images = json.loads(data["images"])
print(f"images = {images}")

Create Video GenerationPOSThttps://api.basicrouter.ai/api/v1/video-generations

ส่งงานสร้างวิดีโอแบบอะซิงโครนัส ส่งคืน taskId ทันที ดึงผลลัพธ์โดยโพล GET /v1/video-generations/{taskId} หรือผ่าน เว็บฮุก callbackUrl

model ค่า videoType ที่อนุญาต ช่วงระยะเวลา (videoDurationMin/Max) resolution / ratio ที่รองรับ และขีดจำกัดการอัปโหลดเนื้อหาอ้างอิง (fileMax) ต้อง ได้รับจาก GET /v1/video-models ก่อน ยอมรับเฉพาะ รหัส videoType ที่ระบุใน allowedVideoTypes ของโมเดลนั้นเท่านั้น

ฟิลด์ประเภทจำเป็นคำอธิบาย
textStringใช่พร้อมต์
modelStringใช่ชื่อโมเดล
videoTypeIntegerใช่1 ข้อความเป็นวิดีโอ / 2 ภาพเป็นวิดีโอ (เฟรมแรก) / 3 ภาพเป็นวิดีโอ (เฟรมแรกและเฟรมสุดท้าย) / 4 ภาพเป็นวิดีโอ (อ้างอิง) / 5 อ้างอิงทั้งหมด
imageUrlsString[]ไม่URL เนื้อหาภาพ
videoUrlsVideoUrl[]|String[]ไม่URL เนื้อหาวิดีโอ
audioUrlsString[]ไม่URL เนื้อหาเสียง
resolutionStringไม่ความละเอียด
ratioStringไม่อัตราส่วนภาพ
durationLongไม่วินาที (>0)
callbackUrlStringไม่URL เว็บฮุกระดับงาน

ตัวอย่างสำหรับแต่ละ videoType:

1. ข้อความเป็นวิดีโอ (videoType=1)

สร้างวิดีโอจากพร้อมต์ข้อความเท่านั้น ไม่ต้องมีเนื้อหาอ้างอิง

curl --request POST \
  --url https://api.basicrouter.ai/api/v1/video-generations \
  --header "Authorization: Bearer $BASICROUTER_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "videoType": 1,
    "text": "A cat jumping on a bed",
    "resolution": "480p",
    "ratio": "16:9",
    "duration": 4,
    "model": "seedance-2.0"
  }'

2. ภาพเป็นวิดีโอ - เฟรมแรก (videoType=2)

ระบุเฟรมเริ่มต้นเดียวใน imageUrls โมเดลจะสร้างวิดีโอ เริ่มจากเฟรมนั้น

curl --request POST \
  --url https://api.basicrouter.ai/api/v1/video-generations \
  --header "Authorization: Bearer $BASICROUTER_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "videoType": 2,
    "text": "Happily shaking head",
    "resolution": "480p",
    "ratio": "16:9",
    "duration": 4,
    "model": "seedance-2.0",
    "imageUrls": ["https://basicrouter-flie.oss-accelerate.aliyuncs.com/test/first-frame.png"]
  }'

3. ภาพเป็นวิดีโอ - เฟรมแรกและสุดท้าย (videoType=3)

ระบุทั้งเฟรมแรกและสุดท้ายใน imageUrls (ลำดับ: [first, last]) โมเดลจะสร้างวิดีโอเปลี่ยนผ่านระหว่างสอง เฟรม

curl --request POST \
  --url https://api.basicrouter.ai/api/v1/video-generations \
  --header "Authorization: Bearer $BASICROUTER_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "videoType": 3,
    "text": "Put on the hat",
    "resolution": "480p",
    "ratio": "16:9",
    "duration": 4,
    "model": "seedance-2.0",
    "imageUrls": [
      "https://basicrouter-flie.oss-accelerate.aliyuncs.com/test/first-frame.png",
      "https://basicrouter-flie.oss-accelerate.aliyuncs.com/test/last-frame.png"
    ]
  }'

4. ภาพเป็นวิดีโอ - อ้างอิง (videoType=4)

ระบุภาพอ้างอิงหนึ่งภาพขึ้นไปใน imageUrls โมเดลจะใช้ สไตล์/เนื้อหาเป็นอ้างอิง (ไม่ใช่เฟรมแรก/สุดท้ายที่บังคับ) เพื่อสร้างวิดีโอ

curl --request POST \
  --url https://api.basicrouter.ai/api/v1/video-generations \
  --header "Authorization: Bearer $BASICROUTER_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "videoType": 4,
    "text": "Two cats playing together",
    "resolution": "480p",
    "ratio": "16:9",
    "duration": 4,
    "model": "kling-v3-omni-video",
    "imageUrls": [
      "https://basicrouter-flie.oss-accelerate.aliyuncs.com/test/ref-1.png",
      "https://basicrouter-flie.oss-accelerate.aliyuncs.com/test/ref-2.png"
    ]
  }'

5. อ้างอิงทั้งหมด (videoType=5)

อ้างอิงภาพ / วิดีโอ / เสียงแบบผสม อ้างอิงเนื้อหาตามตำแหน่งในพร้อมต์: รายการ ที่ 1 ใน imageUrls คือ @图片 1 รายการที่ 1 ใน videoUrls คือ @视频 1 รายการที่ 1 ใน audioUrls คือ @音频 1 videoUrls ยังยอมรับสตริง URL แบบธรรมดา

curl --request POST \
  --url https://api.basicrouter.ai/api/v1/video-generations \
  --header "Authorization: Bearer $BASICROUTER_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "videoType": 5,
    "text": "Use the first-person framing of @视频 1 and @音频 1 as background music. First-person tea ad; start frame is @图片 1 ... end frame is @图片 2.",
    "model": "seedance-2.0",
    "imageUrls": [
      "https://ark-project.tos-cn-beijing.volces.com/doc_image/r2v_tea_pic1.jpg",
      "https://ark-project.tos-cn-beijing.volces.com/doc_image/r2v_tea_pic2.jpg"
    ],
    "videoUrls": ["https://ark-project.tos-cn-beijing.volces.com/doc_video/r2v_tea_video1.mp4"],
    "audioUrls": ["https://ark-project.tos-cn-beijing.volces.com/doc_audio/r2v_tea_audio1.mp3"],
    "resolution": "1080p",
    "ratio": "16:9",
    "duration": 11
  }'

การตอบกลับการส่ง (ทั้งห้าประเภท):

{
  "code": 200,
  "message": "success",
  "data": {"taskId": "vid_xxx"}
}

Retrieve Video GenerationGEThttps://api.basicrouter.ai/api/v1/video-generations/{taskId}

โพลงานสร้างวิดีโอ status คือ pending / success / failed videoUrl คือ URL ของวิดีโอที่สร้างขึ้น และ lastFrameUrl คือ URL ของเฟรมสุดท้าย (สถานการณ์ภาพเป็นวิดีโอ)

curl --request GET \
  --url https://api.basicrouter.ai/api/v1/video-generations/vid_xxx \
  --header "Authorization: Bearer $BASICROUTER_API_KEY"
{
  "code": 200,
  "message": "success",
  "data": {
    "status": "success",
    "videoUrl": "https://.../out.mp4",
    "lastFrameUrl": null,
    "message": null
  }
}

ฟิลด์ data การตอบกลับ:

ฟิลด์ประเภทคำอธิบาย
statusStringpending / success / failed.
videoUrlStringURL วิดีโอที่สร้าง
lastFrameUrlStringURL เฟรมสุดท้าย (กรณีภาพเป็นวิดีโอ) มิฉะนั้นเป็น null
messageStringเหตุผลความล้มเหลว null เมื่อสำเร็จ

หากระบุ callbackUrl ไว้ตอนส่ง เซิร์ฟเวอร์จะส่งผลลัพธ์ขั้นสุดท้าย ผ่านเว็บฮุกด้วยรูปแบบ data เดียวกัน

ตัวอย่างแบบเต็ม (ส่ง + โพล)

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 VideoGenerationExample {
  private static final String BASE = "https://api.basicrouter.ai/api/v1";
  private static final String API_KEY = System.getenv("BASICROUTER_API_KEY");

  public static void main(String[] args) throws Exception {
    HttpClient http = HttpClient.newBuilder()
        .connectTimeout(Duration.ofSeconds(10)).build();

    // 1. Submit the task (videoType=1: text-to-video).
    String body = "{"
        + "\"videoType\":1,"
        + "\"text\":\"A cat jumping on a bed\","
        + "\"resolution\":\"480p\","
        + "\"ratio\":\"16:9\","
        + "\"duration\":4,"
        + "\"model\":\"seedance-2.0\""
        + "}";
    HttpResponse<String> submit = http.send(
        HttpRequest.newBuilder(URI.create(BASE + "/video-generations"))
            .header("Authorization", "Bearer " + API_KEY)
            .header("Content-Type", "application/json")
            .POST(HttpRequest.BodyPublishers.ofString(body)).build(),
        HttpResponse.BodyHandlers.ofString());

    String taskId = extract(submit.body(), "taskId");
    System.out.println("taskId = " + taskId);

    // 2. Poll until terminal status. Video tasks take longer — poll every 20s.
    String status = "pending";
    String lastBody = null;
    while ("pending".equals(status)) {
      Thread.sleep(20_000L);
      HttpResponse<String> poll = http.send(
          HttpRequest.newBuilder(URI.create(BASE + "/video-generations/" + taskId))
              .header("Authorization", "Bearer " + API_KEY).GET().build(),
          HttpResponse.BodyHandlers.ofString());
      lastBody = poll.body();
      status = extract(lastBody, "status");
      System.out.println("status = " + status);
    }

    if (!"success".equals(status)) {
      throw new RuntimeException("video generation failed: " + status);
    }
    String videoUrl = extract(lastBody, "videoUrl");
    System.out.println("videoUrl = " + videoUrl);
  }

  // Minimal JSON field extractor — use Jackson/Gson in production.
  private static String extract(String json, String field) {
    int i = json.indexOf("\"" + field + "\":");
    if (i < 0) return null;
    i += field.length() + 3;
    if (json.charAt(i) == '\"') {
      int end = json.indexOf('\"', i + 1);
      return json.substring(i + 1, end);
    }
    int end = i;
    while (end < json.length() && "0123456789.".indexOf(json.charAt(end)) >= 0) end++;
    return json.substring(i, end);
  }
}
import os
import time
import requests

BASE = "https://api.basicrouter.ai/api/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['BASICROUTER_API_KEY']}"}

# 1. Submit the task (videoType=1: text-to-video).
resp = requests.post(
    f"{BASE}/video-generations",
    headers={**HEADERS, "Content-Type": "application/json"},
    json={
        "videoType": 1,
        "text": "A cat jumping on a bed",
        "resolution": "480p",
        "ratio": "16:9",
        "duration": 4,
        "model": "seedance-2.0",
    },
)
resp.raise_for_status()
task_id = resp.json()["data"]["taskId"]
print(f"taskId = {task_id}")

# 2. Poll until terminal status. Video tasks take longer — poll every 20s.
while True:
    time.sleep(20)
    poll = requests.get(f"{BASE}/video-generations/{task_id}", headers=HEADERS)
    poll.raise_for_status()
    data = poll.json()["data"]
    status = data["status"]
    print(f"status = {status}")
    if status != "pending":
        break

if status != "success":
    raise RuntimeError(f"video generation failed: {data.get('message')}")

print(f"videoUrl = {data['videoUrl']}")
if data.get("lastFrameUrl"):
    print(f"lastFrameUrl = {data['lastFrameUrl']}")

Retrieve Billing BalanceGEThttps://api.basicrouter.ai/api/v1/billing/balance

ส่งคืนยอดคงเหลือบัญชีแบ่งเป็นกระเป๋าเงินสามใบ: แผนรายเดือน แพ็กเกจทรัพยากร และ เครดิตจ่ายตามการใช้งาน

curl --request GET \
  --url https://api.basicrouter.ai/api/v1/billing/balance \
  --header "Authorization: Bearer $BASICROUTER_API_KEY"
{
  "totalCredit": 128.50,
  "totalResourceCredit": 30.00,
  "wallets": {
    "monthlyPlan": {"id": "pkg_xxx", "credit": 50.00, "name": "Monthly plan"},
    "resourcePacks": [
      {"id": "rp_xxx", "credit": 30.00, "name": "Video resource pack"}
    ],
    "payAsYouGo": 48.50
  }
}

ฟิลด์การตอบกลับ:

ฟิลด์ประเภทคำอธิบาย
totalCreditBigDecimalยอดคงเหลือรวม
totalResourceCreditBigDecimalผลรวมยอดคงเหลือแพ็กเกจทรัพยากร
wallets.monthlyPlanWalletDetailแผนรายเดือน (null หากไม่มี)
wallets.resourcePacksWalletDetail[]รายการแพ็กเกจทรัพยากร
wallets.payAsYouGoBigDecimalยอดคงเหลือจ่ายตามการใช้งาน

WalletDetailVO fields::

ฟิลด์ประเภทคำอธิบาย
idStringรหัสกระเป๋าเงิน
creditBigDecimalเครดิตคงเหลือ
nameStringชื่อกระเป๋าเงิน

List UsageGEThttps://api.basicrouter.ai/api/v1/usage

รายละเอียดการเรียกเก็บเงินการเรียกโมเดลแบบแบ่งหน้า สแนปชอตตามราคา (priceSnapshotId) เรียงตามเวลาสร้างคำสั่งซื้อจากมากไปน้อย ส่งคืนเฉพาะ ระเบียนค่าใช้จ่ายปกติ (reason = model usage) เท่านั้น

พารามิเตอร์การค้นหา:

พารามิเตอร์ประเภทจำเป็นค่าเริ่มต้นคำอธิบาย
pageIntegerไม่1หมายเลขหน้า เริ่มจาก 1
sizeIntegerไม่20ขนาดหน้า (แบ่งหน้าตาม priceSnapshotId)
startTimeLocalDateTimeไม่—เวลาเริ่มต้น รูปแบบ yyyy-MM-ddTHH:mm:ss กรองตาม orderCreatedAt ของสแนปชอต
endTimeLocalDateTimeไม่—เวลาสิ้นสุด รูปแบบ yyyy-MM-ddTHH:mm:ss
curl --request GET \
  --url "https://api.basicrouter.ai/api/v1/usage?page=1&size=20&startTime=2026-07-01T00:00:00&endTime=2026-07-31T23:59:59" \
  --header "Authorization: Bearer $BASICROUTER_API_KEY"

ตัวห่อหุ้มการตอบกลับ:

{
  "code": 0,
  "message": "success",
  "data": { ... }
}
ฟิลด์ประเภทคำอธิบาย
recordsUsageDetailVO[]ระเบียนหน้าปัจจุบัน
totalLongจำนวนรวม
currentLongหน้าปัจจุบัน
sizeLongขนาดหน้า
pagesLongหน้าทั้งหมด

ฟิลด์ของ UsageDetailVO:

ฟิลด์ประเภทคำอธิบาย
priceSnapshotIdStringรหัสสแนปชอตราคา
taskIdStringรหัสงาน
creditBigDecimalจำนวนเงินที่เรียกเก็บ
modelStringชื่อโมเดล
modelTypeStringtext / image / video.
inputTokensLongโทเค็นอินพุต null สำหรับภาพ/วิดีโอ
outputTokensLongโทเค็นเอาต์พุต
totalTokensLongโทเค็นรวม
cacheReadTokensLongโทเค็นอ่านแคช
cacheWriteTokensLongโทเค็นเขียนแคช
imageCountIntegerจำนวนภาพ ตั้งค่าสำหรับโมเดลภาพ
imageResolutionStringความละเอียดภาพ เช่น 720P
imageRatioStringอัตราส่วนภาพ เช่น 1:1
videoResolutionStringความละเอียดวิดีโอ เช่น 1080p
videoRatioStringอัตราส่วนวิดีโอ เช่น 16:9
videoDurationSecLongระยะเวลาวิดีโอเป็นวินาที
orderCreatedAtLocalDateTimeเวลาสร้างคำสั่งซื้อ (สแนปชอต orderCreatedAt)
creditDetailsCreditDetailItem[]รายละเอียดคำสั่งซื้อภายใต้สแนปชอตนี้ (จาก credit_order_t)

ฟิลด์ของ CreditDetailItem:

ฟิลด์ประเภทคำอธิบาย
creditBigDecimalจำนวนเงินที่เรียกเก็บโดยคำสั่งซื้อนี้
deductionSourceStringแหล่งที่มาของการหักเงิน (Balance / Monthly Package / Resource Package)
packageNameStringชื่อแพ็กเกจ null หากไม่มีแพ็กเกจ

อนุสัญญาค่าว่าง: เฉพาะฟิลด์ที่เกี่ยวข้องกับแต่ละ modelType เท่านั้นที่ ถูกเติม ส่วนที่เหลือเป็น null text เติมฟิลด์โทเค็น image เติม imageCount/imageResolution/imageRatio video เติม videoResolution/videoRatio/videoDurationSec

ตัวอย่างการตอบกลับ:

{
  "code": 200,
  "message": "success",
  "data": {
    "records": [
      {
        "priceSnapshotId": "snap_9f3c1a2b",
        "taskId": "task_5e8a1c33",
        "credit": 0.0342,
        "model": "glm-5.2",
        "modelType": "text",
        "inputTokens": 1280,
        "outputTokens": 642,
        "totalTokens": 1922,
        "cacheReadTokens": 0,
        "cacheWriteTokens": 0,
        "imageCount": null,
        "imageResolution": null,
        "imageRatio": null,
        "videoResolution": null,
        "videoRatio": null,
        "videoDurationSec": null,
        "orderCreatedAt": "2026-07-18T14:23:11",
        "creditDetails": [
          {
            "credit": 0.0342,
            "deductionSource": "balance",
            "packageName": ""
          }
        ]
      },
      {
        "priceSnapshotId": "snap_a12f77c0",
        "taskId": "task_c71e44a2",
        "credit": 1.8000,
        "model": "seedance-2.0",
        "modelType": "video",
        "inputTokens": null,
        "outputTokens": null,
        "totalTokens": null,
        "cacheReadTokens": null,
        "cacheWriteTokens": null,
        "imageCount": null,
        "imageResolution": null,
        "imageRatio": null,
        "videoResolution": "1080p",
        "videoRatio": "16:9",
        "videoDurationSec": 8,
        "orderCreatedAt": "2026-07-17T22:41:09",
        "creditDetails": [
          {
            "credit": 1.5000,
            "deductionSource": "Monthly Package",
            "packageName": "基础月度套餐"
          },
          {
            "credit": 0.3000,
            "deductionSource": "Resource Package",
            "packageName": "byteplus视频资源包"
          }
        ]
      }
    ],
    "total": 128,
    "current": 1,
    "size": 20,
    "pages": 7
  }
}

List Billing TransactionsGEThttps://api.basicrouter.ai/api/v1/billing/transactions

รายการแบบแบ่งหน้าของธุรกรรมการเติมเงินที่ชำระแล้ว (status=2) ของผู้ใช้ปัจจุบัน เรียงตาม created_at จากมากไปน้อย

พารามิเตอร์ประเภทจำเป็นค่าเริ่มต้นคำอธิบาย
pageIntegerไม่1หมายเลขหน้า
sizeIntegerไม่20ขนาดหน้า
startTimeStringไม่—เวลาเริ่มต้น yyyy-MM-dd HH:mm:ss รวม
endTimeStringไม่—เวลาสิ้นสุด yyyy-MM-dd HH:mm:ss รวม
curl --request GET \
  --url "https://api.basicrouter.ai/api/v1/billing/transactions?page=1&size=20&startTime=2026-07-01%2000:00:00&endTime=2026-07-31%2023:59:59" \
  --header "Authorization: Bearer $BASICROUTER_API_KEY"

ตัวห่อหุ้มการตอบกลับ:

{
  "code": 0,
  "message": "success",
  "data": { ... }
}
ฟิลด์ประเภทคำอธิบาย
recordsTransactionVO[]ธุรกรรมหน้าปัจจุบัน
totalLongจำนวนรวม
currentLongหน้าปัจจุบัน
sizeLongขนาดหน้า
pagesLongหน้าทั้งหมด

ฟิลด์ของ TransactionVO:

ฟิลด์ประเภทคำอธิบาย
orderNoStringหมายเลขคำสั่งซื้อ
thirdPartyOrderNoStringหมายเลขคำสั่งซื้อบุคคลที่สาม
amountBigDecimalจำนวนเงินคำสั่งซื้อ
actualAmountBigDecimalจำนวนเงินที่ชำระจริง
discountBigDecimalจำนวนเงินส่วนลด
paymentMethodStringวิธีชำระเงิน (wechat / alipay / ustd / stripe / wallyt เป็นต้น)

ฟิลด์ของ TransactionVO:

ฟิลด์ประเภทคำอธิบาย
serviceFeeAmountBigDecimalจำนวนเงินค่าธรรมเนียมบริการ
paymentChannelStringแพลตฟอร์มการชำระเงิน
sourceStringแหล่งที่มาของคำสั่งซื้อ (recharge / package_purchase เป็นต้น)
packageNameStringชื่อแพ็กเกจ (ตั้งค่าเมื่อซื้อแพ็กเกจ; การเติมเงินทั่วไปเป็น null)
createdAtLocalDateTimeเวลาที่สร้าง
{
  "code": 200,
  "message": "success",
  "data": {
    "records": [
      {
        "orderNo": "R20260718abc123",
        "thirdPartyOrderNo": "wx_pay_xxx",
        "amount": 50.00,
        "actualAmount": 48.50,
        "discount": 1.50,
        "paymentMethod": "wechat",
        "serviceFeeAmount": 0.00,
        "paymentChannel": "wechat",
        "source": "recharge",
        "packageName": null,
        "createdAt": "2026-07-18T14:23:11"
      }
    ],
    "total": 28,
    "current": 1,
    "size": 20,
    "pages": 2
  }
}