# ScalingTensor API reference

Use one API key to call chat models and asynchronous media-generation models. This reference matches the current ApiChatController and ApiMediaController contracts.

Canonical documentation: https://scalingtensor.com/docs

## Base URL
https://restapi.scalingtensor.com

## Authentication
Except for the model list, chat and media calls require the key created in the Console in the apiKey request header. Do not use Authorization or expose keys in browser code.

```http
Content-Type: application/json
apiKey: YOUR_API_KEY
```

## Response format
Every endpoint returns the same envelope. A request is successful only when code is 0; an HTTP success alone does not indicate business success. time and Long identifiers may be serialized as strings.

```json
{
  "code": 0,
  "data": { ... },
  "msg": "成功",
  "time": "1788483942311",
  "requestId": "trace-id",
  "success": true
}
```

## Public model catalog
GET /v1/models — no API key required. A successful response has code: 0 and a data array with slug, displayName, type and priceConfig.

## Chat
POST /api/chat/completion
This endpoint is synchronous. messages are passed to the active model adapter. The current controller accepts only model and messages as top-level fields.
This API is not wire-compatible with the OpenAI SDK. Use the apiKey header and read code and data; chat data contains content, tokensIn, tokensOut and costMicros. Streaming is not exposed by this endpoint.
Use a chat model ID from the current catalog. The following snippet illustrates the request format.

```bash
curl -X POST https://restapi.scalingtensor.com/api/chat/completion \
  -H "Content-Type: application/json" \
  -H "apiKey: YOUR_API_KEY" \
  -d '{
    "model": "openai/gpt-4o-mini",
    "messages": [
      {"role": "user", "content": "Hello!"}
    ]
  }'
```


```json
{
  "code": 0,
  "data": {
    "content": "Hello! How can I help?",
    "tokensIn": 8,
    "tokensOut": 7,
    "costMicros": "6"
  },
  "msg": "成功"
}
```

## Media generation
POST /api/media/generate
Media generation is asynchronous. Save the returned jobId and poll the result endpoint. params are forwarded according to the model provider, so available fields depend on the selected model.

```bash
curl -X POST https://restapi.scalingtensor.com/api/media/generate \
  -H "Content-Type: application/json" \
  -H "apiKey: YOUR_API_KEY" \
  -d '{
    "model": "sonilo/text-to-music",
    "params": {
      "prompt": "Warm ambient music for a product demo",
      "duration": 30,
      "variants_num": 1
    }
  }'
```


```json
{
  "code": 0,
  "data": { "jobId": "724958320123", "status": "pending" },
  "msg": "成功"
}
```

## Poll a media job
GET /api/media/result?jobId=...
Poll with the jobId returned during submission. A job can only be read by the user that owns the API key used to create it. Poll every 2–5 seconds until completed or failed.

```bash
curl "https://restapi.scalingtensor.com/api/media/result?jobId=724958320123" \
  -H "apiKey: YOUR_API_KEY"
```


```json
{
  "code": 0,
  "data": {
    "status": "completed",
    "resultData": {
      "status": "completed",
      "output_url": "https://.../result.mp3"
    }
  },
  "msg": "成功"
}
```

## Media parameters
params for general media models are provider-defined. When priceConfig.api_reference_url is present in the model list, use that model reference. The backend explicitly validates the Sonilo parameters below.

- sonilo/text-to-music: prompt (1–2,000 chars), duration (integer, 5–360 seconds); optional segments, output_format, variants_num (1–10)
- sonilo/text-to-sfx: prompt (1–2,000 chars), duration (integer, 1–180 seconds); optional audio_format: wav/mp3/aac/flac
- sonilo/video-to-music: video_url (public direct HTTP(S) video URL); optional prompt, segments, preserve_speech, isolate_vocals, output_format, ducking, variants_num, stems, prompt_influence, lyrics
- sonilo/video-to-sfx: video_url; optional prompt (up to 2,000 chars), audio_format, segments (1–30 contiguous items with start, end, prompt)
- sonilo/dubbing: video_url; optional languages (unique language-code array), ducking (boolean)

video_url must be a public, direct HTTP(S) URL without redirects and contain readable video. The JSON endpoint does not support binary video uploads.
## Billing
Chat pricing uses input and output tokens. Media pricing can depend on jobs, duration, output quantity or upstream actual cost. Read each model’s priceConfig and model page. costMicros is denominated in microdollars (1 USD = 1,000,000 microdollars).

## Errors
Business errors use the same response envelope. Check code before reading data. Common codes are listed below.

- 0: Success
- 3: Rate limited
- 5: Internal server error
- 1000: General business error
- 1001: Invalid parameters
- 1003: Model/job not found, or job belongs to another user
- 1008: Invalid or revoked API key
- 1009: Insufficient wallet balance
- 1012: Video is too large to inspect
- 1013: Could not determine a positive video duration

## Security and retries
- Keep API keys on your server or in a secure secret manager.
- Decide carefully whether to retry chat calls to avoid duplicate charges.
- After a media submission succeeds, do not resubmit; store jobId and poll it.
- Use exponential backoff only for rate limits, network failures, and server errors.

## Links
- [Model marketplace](https://scalingtensor.com/models)
- [Machine-readable site index](https://scalingtensor.com/llms.txt)
