# LINGTU AI OpenAPI

- OpenAPI: 3.1.2
- API version: 1.7.0
- Last updated: 2026-08-23
- Base URL: `https://api.ailingtu.com`
- Authentication: `x-api-key: <YOUR_API_KEY>`
- Success condition: HTTP 2xx and response `code === 0`

Machine-readable descriptions: [JSON](/openapi.json) · [YAML](/openapi.yaml) · [operation index](/openapi/operations/index.json)

API keys must remain on the server and must not be included in browser code, logs, or shared files.

## Publishing workflow

1. Create a TikTok Shop authorization URL for the target `oauthRegion` and complete creator authorization.
2. Query the authorized creator account.
3. Query showcase products with the account `id`.
4. Create a presigned upload, PUT new files to object storage, and confirm them.
5. Create a publishing task with the account `creatorId` and uploaded `fileId`.
6. Query publishing records with the returned `postId` until the task reaches a terminal status.

## AI generation workflow

See the focused [AI generation workflow](/openapi/workflows/ai-generation.md).

1. Create an image or video schedule with `POST /v1/ai/schedule/create`.
2. Save the returned `scheduleId`.
3. Poll `GET /v1/ai/task/listByScheduleId?scheduleId=...` until the requested tasks complete or explicitly fail.
4. Read the generated image or video URL from the completed task result.

## Viral video replication workflow

1. Send `POST /v1/material/analysisTask/stream` with `type: REPLICATION` and a public video URL, or upload a file first and send `businessId` with `businessType`.
2. Read the `text/event-stream` response. Each `data:` line is a JSON object.
3. Concatenate `result` from `status: "streaming"` events in arrival order. If a `status: "done"` event arrives, use that `result` as the complete prompt.
4. Optionally pass the assembled prompt to `POST /v1/ai/schedule/create` to generate a remake video.

## Creator analysis workflow

1. Fetch recent public posts with `GET /v1/influencer/fetchPosts` for TikTok or `GET /v1/influencer/ins/fetchPosts` for Instagram.
2. Calculate deterministic evidence such as posting cadence, top posts, engagement rates, themes, and hashtag frequency.
3. Send only the required evidence to `POST /v1/relay/chat/completions` to generate a decision-oriented report.
4. Keep observed metrics separate from AI inference and explicitly preserve missing-data limitations.

## GET /v1/creatorAccount/tiktokShopOauth/authorize

Operation ID: `createTikTokShopAuthorizationUrl`

Create a TikTok Shop creator authorization URL

Creates a TikTok Shop OAuth authorization URL for the selected market and shop type. Open the returned URL in a browser or render it as a QR code, then complete authorization in TikTok Shop.

| Field | Location | Type | Required | Description |
|---|---|---|---:|---|
| `oauthRegion` | query | `us_cross` \| `us_local` \| `br_local` \| `br_cross` \| `mx_local` \| `mx_cross` \| `gb_local` \| `de_local` \| `de_cross` \| `fr_local` \| `fr_cross` \| `es_local` \| `es_cross` \| `it_local` \| `it_cross` \| `ie_local` \| `ie_cross` \| `jp_local` \| `jp_cross` \| `th_local` \| `th_cross` \| `my_local` \| `my_cross` \| `id_local` \| `id_cross` \| `sg_local` \| `sg_cross` \| `vn_local` \| `vn_cross` \| `ph_local` \| `ph_cross` | yes | TikTok Shop authorization market and shop type. Values ending in _local are local shops; values ending in _cross are cross-border shops. |

### Success response

```json
{
  "code": 0,
  "data": {
    "url": "https://services.tiktokshop.com/open/authorize?service_id=example&state=example"
  },
  "message": "success"
}
```

### Important notes

- Use us_cross for US cross-border shops and us_local for US local or ACCU shops.
- UK cross-border authorization is no longer available; use gb_local only.
- Request the URL from your server with the API key; never expose the API key in browser code.

### Errors

| HTTP | Meaning |
|---:|---|
| 400 | Invalid request parameters or body. |
| 401 | The API key is missing or invalid. |
| 403 | The API key does not have permission for this operation. |
| 429 | Too many requests. Retry with exponential backoff. |
| 500 | Unexpected server error. Retry transient failures with exponential backoff. |


## GET /v1/creatorAccount/pageList

Operation ID: `listCreatorAccounts`

List authorized creator accounts

Returns authorized creator accounts and publishing permissions. Use `id` for product queries and `creatorId` when creating publishing tasks.

| Field | Location | Type | Required | Description |
|---|---|---|---:|---|
| `pageSize` | query | integer | yes | Items per page. |
| `pageNumber` | query | integer | yes | Page number starting at 1. |
| `valid` | query | boolean | no | Return valid authorizations only. |
| `authSource` | query | `TIKTOK_SHOP_CREATOR` \| `TIKTOK_LOGIN_KIT` | no | Authorization source. Use TIKTOK_SHOP_CREATOR for commerce publishing. |
| `usernames` | query | string[] | no | TikTok usernames. Repeat the query parameter for multiple values. |
| `selectionRegion` | query | string | no | Target TikTok Shop region. |
| `hasPhotoPermission` | query | boolean | no | Return accounts with shoppable photo permission only. |

### Success response

```json
{
  "code": 0,
  "data": {
    "list": [
      {
        "id": 12345,
        "creatorId": "2077242233106595840",
        "username": "shop_creator",
        "authSource": "TIKTOK_SHOP_CREATOR",
        "oauthRegion": "USA",
        "registerRegion": "US",
        "selectionRegion": "US",
        "targetMarket": "US",
        "valid": true,
        "tagNames": [
          "top-tier"
        ],
        "permissions": [
          "VIDEO_SHOPPABLE_PERMISSION",
          "PHOTO_SHOPPABLE_PERMISSION_PRODUCT"
        ]
      }
    ],
    "total": 1,
    "pageNumber": 1,
    "pageSize": 200,
    "totalPages": 1
  },
  "message": "success"
}
```

### Important notes

- Photo posts require PHOTO_SHOPPABLE_PERMISSION_PRODUCT in permissions.

### Errors

| HTTP | Meaning |
|---:|---|
| 400 | Invalid request parameters or body. |
| 401 | The API key is missing or invalid. |
| 403 | The API key does not have permission for this operation. |
| 429 | Too many requests. Retry with exponential backoff. |
| 500 | Unexpected server error. Retry transient failures with exponential backoff. |


## GET /v1/creator/tiktokshop/product/listByShowcase

Operation ID: `listTikTokShowcaseProducts`

List creator showcase products

Lists products in a creator showcase. Use `SHOWCASE` as the product source when creating a publishing task.

| Field | Location | Type | Required | Description |
|---|---|---|---:|---|
| `id` | query | integer | yes | Creator account table ID. |
| `origin` | query | `TIKTOK` | yes | Product platform origin. |
| `pageSize` | query | integer | yes | Items per page. |
| `pageToken` | query | string | no | Pagination token from the previous response. |

### Success response

```json
{
  "code": 0,
  "data": {
    "products": [
      {
        "id": "1732280564607717841",
        "title": "Summer Vibes Cord",
        "price": {
          "amount": "19.99",
          "currency": "USD"
        },
        "images": [
          {
            "url": "https://cdn.example.com/product.jpg",
            "width": 800,
            "height": 800
          }
        ]
      }
    ],
    "nextPageToken": "",
    "totalCount": 1
  },
  "message": "success"
}
```

### Important notes

- This endpoint does not accept titleKeyword. Filter by title on the client when needed.

### Errors

| HTTP | Meaning |
|---:|---|
| 400 | Invalid request parameters or body. |
| 401 | The API key is missing or invalid. |
| 403 | The API key does not have permission for this operation. |
| 429 | Too many requests. Retry with exponential backoff. |
| 500 | Unexpected server error. Retry transient failures with exponential backoff. |


## POST /v1/creator/tiktokshop/product/addToShowcase

Operation ID: `addTikTokShowcaseProducts`

Add products to a creator showcase

Adds TikTok Shop products to an authorized creator showcase. Use PRODUCT_ID with 1–20 productIds, or PRODUCT_LINK with productLink. A response with code 0 can still contain data.errors when some products failed to be added. The creator authorization must include creator.showcase.write and creator.video.write.

| Field | Location | Type | Required | Description |
|---|---|---|---:|---|
| `id` | body | integer | yes | Creator account id |
| `addType` | body | PRODUCT_ID \| PRODUCT_LINK | yes | How products are identified |
| `productIds` | body | string[] | conditional | Required for PRODUCT_ID; 1–20 product IDs |
| `productLink` | body | string(uri) | conditional | Required for PRODUCT_LINK |

### Request example: Add by product IDs

```json
{
  "id": 12345,
  "addType": "PRODUCT_ID",
  "productIds": [
    "1732280564607717841",
    "1732280564607717842"
  ]
}
```

### Request example: Add by product link

```json
{
  "id": 12345,
  "addType": "PRODUCT_LINK",
  "productLink": "https://shop.tiktok.com/view/product/1732280564607717841"
}
```

### Success response: All products added

```json
{
  "code": 0,
  "data": {},
  "message": "success",
  "timestamp": 1786406400000
}
```

### Success response: Some products failed

```json
{
  "code": 0,
  "data": {
    "errors": [
      {
        "code": 16001001,
        "message": "Product is unavailable for this creator",
        "detail": {
          "productId": "1732280564607717842"
        }
      }
    ]
  },
  "message": "success",
  "timestamp": 1786406400000
}
```

### Success response: Creator authorization expired

```json
{
  "code": 40101,
  "data": {},
  "message": "授权过期，请重新授权",
  "timestamp": 1786406400000
}
```

### Important notes

- Required scopes: creator.showcase.write and creator.video.write.
- A request can contain at most 20 product IDs.
- Check data.errors even when code is 0; entries identify products that failed.
- An expired creator authorization returns the business error “授权过期，请重新授权”.

### Errors

| HTTP | Meaning |
|---:|---|
| 400 | Invalid request parameters or body. |
| 401 | The API key is missing or invalid. |
| 403 | The API key does not have permission for this operation. |
| 429 | Too many requests. Retry with exponential backoff. |
| 500 | Unexpected server error. Retry transient failures with exponential backoff. |


## POST /v1/file/presign

Operation ID: `createFileUpload`

Create a presigned file upload

Returns a file ID and a presigned object-storage URL. When `isNew` is false, skip PUT and confirmation. When `isNew` is true, PUT the raw file bytes to `uploadUrl` with the same Content-Type, without the x-api-key header, then confirm the upload.

| Field | Location | Type | Required | Description |
|---|---|---|---:|---|
| `fileName` | body | string | yes | File name including extension |
| `contentType` | body | string | yes | File MIME type |
| `size` | body | integer | yes | File size in bytes |
| `hash` | body | string | yes | SHA-256 of the UTF-8 encoded lowercase hex representation of the file bytes |

### Request example

```json
{
  "fileName": "video.mp4",
  "contentType": "video/mp4",
  "size": 12345678,
  "hash": "3786a02b..."
}
```

### Success response

```json
{
  "code": 0,
  "data": {
    "fileId": 591,
    "uploadUrl": "https://object-storage.example.com/presigned-url",
    "url": "https://cdn.ailingtu.com/media/video.mp4",
    "isNew": true,
    "expiresAt": "2026-07-29T12:00:00Z"
  },
  "message": "success"
}
```

### Important notes

- When isNew is true, PUT the raw file to uploadUrl with the same Content-Type, then call confirm.
- Do not send x-api-key to the object-storage PUT URL.

### Errors

| HTTP | Meaning |
|---:|---|
| 400 | Invalid request parameters or body. |
| 401 | The API key is missing or invalid. |
| 403 | The API key does not have permission for this operation. |
| 429 | Too many requests. Retry with exponential backoff. |
| 500 | Unexpected server error. Retry transient failures with exponential backoff. |


## POST /v1/file/confirm

Operation ID: `confirmFileUpload`

Confirm a file upload

Call only after a new file is successfully uploaded to its presigned URL. Deduplicated files do not require confirmation.

| Field | Location | Type | Required | Description |
|---|---|---|---:|---|
| `fileId` | body | integer \| string | yes | File ID returned by the presign endpoint |

### Request example

```json
{
  "fileId": 591
}
```

### Success response

```json
{
  "code": 0,
  "data": {
    "fileId": 591,
    "confirmed": true
  },
  "message": "success"
}
```

### Errors

| HTTP | Meaning |
|---:|---|
| 400 | Invalid request parameters or body. |
| 401 | The API key is missing or invalid. |
| 403 | The API key does not have permission for this operation. |
| 429 | Too many requests. Retry with exponential backoff. |
| 500 | Unexpected server error. Retry transient failures with exponential backoff. |


## POST /v1/creator/post/create

Operation ID: `createCreatorPost`

Create a creator publishing task

Creates a TikTok Shop commerce video or photo publishing task. A successful response means the task was accepted, not that TikTok publishing has completed.

| Field | Location | Type | Required | Description |
|---|---|---|---:|---|
| `businessId` | body | string | yes | Video fileId; first image fileId for photo posts |
| `businessType` | body | FILE | yes | Use FILE for uploaded media |
| `creatorId` | body | string | yes | creatorId returned by the creator endpoint |
| `title` | body | string | yes | Post caption, up to 4,000 characters |
| `platform` | body | TIKTOK_SHOP | yes | Use TIKTOK_SHOP for commerce posts |
| `mediaType` | body | VIDEO \| PHOTO | yes | Explicitly select video or photo |
| `scheduledAt` | body | integer | no | Unix epoch in milliseconds |
| `scheduledTz` | body | string | no | IANA timezone |
| `oauthRegion` | body | string | no | Creator OAuth authorization region |
| `coverFileId` | body | integer \| string | no | Custom video cover file ID; pass together with tiktokShop.coverUri and omit for photo posts |
| `tiktokShop` | body | object | conditional | Required for VIDEO; contains product, cover, pre-check, music, and AI label options |
| `tiktokShop.preCheck` | body | boolean | no | Whether to submit a pre-check before publishing; defaults to false |
| `tiktokShop.isAiGenerated` | body | boolean | no | Whether to label the video as AI-generated; TikTok adds an AI-generated label when true |
| `tiktokShop.coverUri` | body | string | no | URI returned by the cover upload endpoint; pass coverFileId with it |
| `tiktokShop.coverTimestampMs` | body | integer | no | Video timestamp in milliseconds to use as the cover frame; omit when coverUri is present |
| `tiktokShop.musicInfo` | body | object | no | Video background music; omit when no music is needed |
| `tiktokShop.musicInfo.id` | body | string | conditional | Music ID, required when musicInfo is provided |
| `tiktokShop.productInfo.productId` | body | string | conditional | Required for VIDEO; product ID returned by the product endpoint |
| `tiktokShop.productInfo.title` | body | string | conditional | Required for VIDEO; product anchor title, up to 30 characters |
| `tiktokShop.productInfo.source` | body | SHOP \| SHOWCASE | conditional | Required for VIDEO; SHOP for shop products or SHOWCASE for showcase products |
| `tiktokShopPhoto` | body | object | conditional | Required for PHOTO |
| `tiktokShopPhoto.postType` | body | MULTI_PHOTO_ONE_ANCHOR | conditional | Use MULTI_PHOTO_ONE_ANCHOR for PHOTO |
| `tiktokShopPhoto.businessIds` | body | string[] | conditional | Required for PHOTO; 1–15 image fileIds in final display order |
| `tiktokShopPhoto.productLinks[0].productId` | body | string | conditional | Required for PHOTO; product ID for the single product anchor |
| `tiktokShopPhoto.productLinks[0].title` | body | string | conditional | Required for PHOTO; product anchor title, up to 30 characters |
| `tiktokShopPhoto.productLinks[0].source` | body | SHOP \| SHOWCASE | conditional | Required for PHOTO; product source |
| `tiktokShopPhoto.musicInfo` | body | object | no | Photo post background music; omit when no music is needed |
| `tiktokShopPhoto.musicInfo.id` | body | string | conditional | Music ID, required when musicInfo is provided |

### Request example: TikTok Shop commerce video

```json
{
  "businessId": "591",
  "businessType": "FILE",
  "creatorId": "2077242233106595840",
  "title": "Summer Sale 2026 #summer",
  "platform": "TIKTOK_SHOP",
  "mediaType": "VIDEO",
  "scheduledAt": 1784896665989,
  "scheduledTz": "America/New_York",
  "oauthRegion": "USA",
  "tiktokShop": {
    "preCheck": false,
    "isAiGenerated": true,
    "coverTimestampMs": 1500,
    "musicInfo": {
      "id": "7567668059796720391",
      "title": "original sound",
      "author": "Ivan",
      "duration": "15"
    },
    "productInfo": {
      "productId": "1732280564607717841",
      "title": "Summer Vibes Cord",
      "source": "SHOP"
    }
  }
}
```

### Request example: TikTok Shop commerce photo post

```json
{
  "businessId": "591",
  "businessType": "FILE",
  "creatorId": "2077242233106595840",
  "title": "Summer Sale 2026 #summer",
  "platform": "TIKTOK_SHOP",
  "mediaType": "PHOTO",
  "scheduledAt": 1784896665989,
  "scheduledTz": "America/New_York",
  "oauthRegion": "USA",
  "tiktokShopPhoto": {
    "postType": "MULTI_PHOTO_ONE_ANCHOR",
    "businessIds": [
      "591",
      "592"
    ],
    "productLinks": [
      {
        "productId": "1732280564607717841",
        "title": "Summer Vibes Cord",
        "source": "SHOP"
      }
    ],
    "musicInfo": {
      "id": "7567668059796720391",
      "title": "original sound",
      "author": "Ivan",
      "duration": "15"
    }
  }
}
```

### Success response

```json
{
  "code": 0,
  "data": {
    "id": 100,
    "postId": "post_xxx",
    "platform": "TIKTOK_SHOP",
    "title": "Summer Sale 2026 #summer",
    "videoUrl": "https://cdn.ailingtu.com/media/video.mp4",
    "status": "SCHEDULED"
  },
  "message": "success"
}
```

### Important notes

- For a video cover, use tiktokShop.coverTimestampMs for a frame or pass coverFileId together with tiktokShop.coverUri for a custom cover; do not mix the two methods.
- Photo posts support 1–15 images and one product; businessId must equal businessIds[0], and the first image is the cover.
- Persist postId and status, then verify the final state in publishing records.

### Errors

| HTTP | Meaning |
|---:|---|
| 400 | Invalid request parameters or body. |
| 401 | The API key is missing or invalid. |
| 403 | The API key does not have permission for this operation. |
| 429 | Too many requests. Retry with exponential backoff. |
| 500 | Unexpected server error. Retry transient failures with exponential backoff. |


## GET /v1/creator/post/pageList

Operation ID: `listCreatorPosts`

List creator publishing records

Returns paginated TikTok and TikTok Shop publishing records. Use this endpoint after creating a publishing task to confirm its current or final status and read platform post identifiers, failure reasons, media, product, and scheduling information.

| Field | Location | Type | Required | Description |
|---|---|---|---:|---|
| `pageSize` | query | integer | yes | Items per page. |
| `pageNumber` | query | integer | yes | Page number starting at 1. |
| `status` | query | `WAITING_SUBMIT` \| `SUBMITTING` \| `PRE_CHECK_SUBMITTING` \| `PRE_CHECK` \| `PRE_CHECK_PASSED` \| `PRE_CHECK_REJECTED` \| `PENDING` \| `PROCESSING` \| `SUCCESS` \| `COMPLETED` \| `FAILED` \| `CANCELLED` \| `SUBMIT_FAILED` | no | Publishing status. |
| `postId` | query | string | no | LINGTU publishing task ID. |
| `title` | query | string | no | Post title or caption keyword. |
| `creatorUsername` | query | string | no | TikTok creator username. |
| `platform` | query | `TIKTOK` \| `TIKTOK_SHOP` | no | Publishing platform. |
| `managerIds` | query | integer[] | no | Account manager IDs. Repeat the query parameter for multiple values. |
| `noManager` | query | boolean | no | Return records for accounts without an assigned manager only. |

### Success response

```json
{
  "code": 0,
  "data": {
    "list": [
      {
        "id": 100,
        "postId": "post_xxx",
        "platform": "TIKTOK_SHOP",
        "title": "Summer Sale 2026 #summer",
        "videoUrl": "https://cdn.ailingtu.com/media/video.mp4",
        "coverUrl": "https://cdn.ailingtu.com/media/video-cover.jpg",
        "reason": null,
        "remark": null,
        "platformPostId": "7541234567890123456",
        "scheduledAt": 1784896665989,
        "scheduledTz": "America/New_York",
        "publishedAt": 1784896765989,
        "status": "COMPLETED",
        "creatorUsername": "shop_creator",
        "createdByName": "Operations Team",
        "productInfo": {
          "productId": "1732280564607717841",
          "title": "Summer Vibes Cord",
          "source": "SHOP"
        },
        "productLinks": null,
        "musicInfo": {
          "id": "7567668059796720391",
          "title": "original sound",
          "author": "Ivan",
          "duration": "15"
        },
        "materialType": "VIDEO",
        "mediaType": "VIDEO",
        "shopMaterialId": null
      }
    ],
    "total": 1,
    "pageNumber": 1,
    "pageSize": 10,
    "totalPages": 1
  },
  "message": "success"
}
```

### Important notes

- The minimal request only needs pageSize and pageNumber, for example ?pageSize=10&pageNumber=1.
- Task creation does not mean platform publishing is complete. Persist postId and use this endpoint to verify the final status.
- SUCCESS, COMPLETED, and PRE_CHECK_PASSED are success-like states; FAILED, SUBMIT_FAILED, and PRE_CHECK_REJECTED are failure-like states.

### Errors

| HTTP | Meaning |
|---:|---|
| 400 | Invalid request parameters or body. |
| 401 | The API key is missing or invalid. |
| 403 | The API key does not have permission for this operation. |
| 429 | Too many requests. Retry with exponential backoff. |
| 500 | Unexpected server error. Retry transient failures with exponential backoff. |


## POST /v1/ai/schedule/create

Operation ID: `createAiGenerationSchedule`

Create an AI media generation schedule

Creates one or more AI image or video generation tasks. Use the returned scheduleId to query task status and generated assets. Keep polling the same schedule until every requested output succeeds or explicitly fails.

| Field | Location | Type | Required | Description |
|---|---|---|---:|---|
| `taskId` | body | string | no | Caller-generated task identifier; an 8-character lowercase alphanumeric value is recommended |
| `type` | body | IMAGE_GENERATION \| VIDEO_GENERATION | yes | Media generation type |
| `params.prompt` | body | string | yes | Image or video generation prompt |
| `params.model` | body | gpt-image-2 \| nano-banana-2 \| nano-banana-2-2k \| nano-banana-2-4k \| seedream5.0-lite \| gemini-omni-video \| veo3.1-lite-extend \| veo3.1-extend \| grok-imagine-1.5 \| seedance2.0-mini \| seedance2.0 \| seedance2.0-fast | yes | Select one of the image or video models listed below, matching type |
| `params.aspectRatio` | body | string | conditional | Required for images, for example 1:1 or 9:16 |
| `params.seconds` | body | integer | conditional | Video duration; allowed values depend on the model |
| `params.size` | body | string | conditional | Video dimensions, for example 720x1280 |
| `params.inputReference` | body | string(uri) | no | One remote reference image URL, primarily for video generation |
| `params.inputReferences` | body | string(uri)[] | no | Ordered remote reference image URLs; data URLs are not supported |
| `params.watermark` | body | boolean | no | Whether to add a video watermark; defaults to false |
| `nums` | body | integer | yes | Number of outputs; use 1 unless multiple results are needed |
| `businessId` | body | string | no | Optional related business object ID |
| `businessType` | body | MERCHANT_SKU \| AI_PURCHASE_TASK | no | Related business object type |
| `promptId` | body | string | no | Saved prompt ID |
| `execAt` | body | string(date-time) | no | ISO 8601 execution time; omit to create immediately |
| `name` | body | string | no | Display name for the generation schedule |

### Request example: Generate an image

```json
{
  "taskId": "img8a1b2",
  "type": "IMAGE_GENERATION",
  "params": {
    "prompt": "A clean product hero image on a bright studio background",
    "model": "gpt-image-2",
    "aspectRatio": "1:1",
    "inputReferences": [
      "https://static.ailingtu.com/ai-images/product-reference.jpg"
    ]
  },
  "nums": 1,
  "name": "Product hero image"
}
```

### Request example: Generate a video

```json
{
  "taskId": "vid8c3d4",
  "type": "VIDEO_GENERATION",
  "params": {
    "prompt": "A clean 10-second product reveal video with a slow camera push-in",
    "model": "gemini-omni-video",
    "seconds": 10,
    "size": "720x1280",
    "inputReferences": [
      "https://static.ailingtu.com/ai-images/product-reference.jpg"
    ],
    "watermark": false
  },
  "nums": 1,
  "name": "Product reveal video"
}
```

### Success response

```json
{
  "code": 0,
  "data": {
    "scheduleId": "schedule_01k1example",
    "taskIds": [
      "task_01k1example"
    ]
  },
  "message": "success"
}
```

### Important notes

- Image models: gpt-image-2, nano-banana-2, nano-banana-2-2k, nano-banana-2-4k, seedream5.0-lite.
- Video models: gemini-omni-video, veo3.1-lite-extend, veo3.1-extend, grok-imagine-1.5, seedance2.0-mini, seedance2.0, seedance2.0-fast.
- Video durations: gemini-omni-video supports 6/8/10s; veo3.1-lite-extend and veo3.1-extend are fixed at 8s; grok-imagine-1.5 supports 6/10/15/20/25/30s; seedance2.0-mini, seedance2.0, and seedance2.0-fast support 4/8/10/12/15s.
- For images, use IMAGE_GENERATION with params.aspectRatio. For videos, use VIDEO_GENERATION with params.seconds and params.size.
- References must be accessible http/https URLs. Upload local files before passing their URLs.
- scheduleId and taskId are different. Query the same scheduleId after creation and do not recreate a task only because polling was interrupted.

### Related operations

- [GET /v1/ai/task/listByScheduleId](/openapi/operations/listAiTasksByScheduleId.md)

### Errors

| HTTP | Meaning |
|---:|---|
| 400 | Invalid request parameters or body. |
| 401 | The API key is missing or invalid. |
| 403 | The API key does not have permission for this operation. |
| 429 | Too many requests. Retry with exponential backoff. |
| 500 | Unexpected server error. Retry transient failures with exponential backoff. |


## GET /v1/ai/task/listByScheduleId

Operation ID: `listAiTasksByScheduleId`

List AI generation tasks by schedule ID

Returns AI image or video generation tasks for one schedule. Poll this endpoint until the requested tasks reach a terminal status and expose their generated asset URLs.

| Field | Location | Type | Required | Description |
|---|---|---|---:|---|
| `scheduleId` | query | string | yes | Schedule ID returned by the schedule creation endpoint. |

### Success response

```json
{
  "code": 0,
  "data": {
    "list": [
      {
        "taskId": "task_01k1example",
        "scheduleId": "schedule_01k1example",
        "type": "VIDEO_GENERATION",
        "status": "COMPLETED",
        "model": "gemini-omni-video",
        "params": {
          "prompt": "A clean 10-second product reveal video with a slow camera push-in",
          "model": "gemini-omni-video",
          "seconds": 10,
          "size": "720x1280"
        },
        "result": {
          "url": "https://static.ailingtu.com/ai-videos/result.mp4",
          "thumbnailUrl": "https://static.ailingtu.com/ai-images/cover.jpg"
        },
        "customResult": {
          "videoUrl": "https://static.ailingtu.com/ai-videos/result.mp4",
          "coverUrl": "https://static.ailingtu.com/ai-images/cover.jpg"
        },
        "createdAt": "2026-08-10T10:00:00Z"
      }
    ],
    "total": 1,
    "pageNumber": 1,
    "pageSize": 20,
    "totalPages": 1
  },
  "message": "success"
}
```

### Important notes

- Waiting states include WAITING_SUBMIT, SUBMITTING, PENDING, and PROCESSING. COMPLETED is successful.
- Retry only after an explicit failure, cancellation, or expiration. A network or polling-process error does not mean generation failed.
- For videos, prefer customResult.videoUrl or result.url. Images usually use result.url or resultUrl.

### Related operations

- [POST /v1/ai/schedule/create](/openapi/operations/createAiGenerationSchedule.md)

### Errors

| HTTP | Meaning |
|---:|---|
| 400 | Invalid request parameters or body. |
| 401 | The API key is missing or invalid. |
| 403 | The API key does not have permission for this operation. |
| 429 | Too many requests. Retry with exponential backoff. |
| 500 | Unexpected server error. Retry transient failures with exponential backoff. |


## GET /v1/influencer/fetchPosts

Operation ID: `fetchTikTokCreatorPosts`

Fetch a TikTok creator profile and recent posts

Returns a public TikTok creator profile and recent posts with views and engagement metrics. Use the response as evidence for creator monitoring, benchmarking, or an AI-generated analysis report.

| Field | Location | Type | Required | Description |
|---|---|---|---:|---|
| `uniqueId` | query | string | yes | TikTok creator username without the leading @. |
| `count` | query | integer | no | Number of recent posts to return. |

### Success response

```json
{
  "code": 0,
  "message": "success",
  "data": {
    "authorInfo": {
      "id": "6614519312189947909",
      "uniqueId": "vacbirdusa",
      "nickname": "Vacbird",
      "signature": "Product finds and everyday solutions",
      "followerCount": 101037,
      "followingCount": 29,
      "awemeCount": 2573,
      "totalFavorited": 644435
    },
    "posts": [
      {
        "videoId": "7634589785687854366",
        "desc": "A useful product find #musthave",
        "createTime": 1777662000,
        "duration": 18100,
        "isAd": false,
        "cover": "https://cdn.example.com/tiktok-cover.jpg",
        "stats": {
          "playCount": 10844609,
          "diggCount": 46314,
          "commentCount": 552,
          "shareCount": 16457,
          "collectCount": 16257,
          "repostCount": 0
        }
      }
    ],
    "cursor": "1",
    "hasMore": true
  },
  "timestamp": 1787417005
}
```

### Important notes

- This operation currently returns TikTok creator data. Do not infer accounts on other platforms from matching usernames.
- Treat the request as successful only when HTTP is 200 and code is 0. code -1 means no public creator posts were available.
- To generate an AI creator report, turn this response into evidence and send it to /v1/relay/chat/completions.

### Related operations

- [POST /v1/relay/chat/completions](/openapi/operations/createRelayChatCompletion.md)

### Errors

| HTTP | Meaning |
|---:|---|
| 400 | Invalid request parameters or body. |
| 401 | The API key is missing or invalid. |
| 403 | The API key does not have permission for this operation. |
| 429 | Too many requests. Retry with exponential backoff. |
| 500 | Unexpected server error. Retry transient failures with exponential backoff. |


## GET /v1/influencer/ins/fetchPosts

Operation ID: `fetchInstagramCreatorPosts`

Fetch an Instagram creator profile and recent posts

Returns a public Instagram creator profile and recent posts. Some list results, especially image or carousel posts, can omit video views or engagement fields.

| Field | Location | Type | Required | Description |
|---|---|---|---:|---|
| `uniqueId` | query | string | yes | Instagram username without the leading @. |
| `count` | query | integer | no | Number of recent posts to return. |

### Success response

```json
{
  "code": 0,
  "message": "success",
  "data": {
    "author": {
      "id": "1234567890",
      "username": "creator",
      "fullName": "Creator",
      "biography": "Product reviews and daily finds",
      "followerCount": 45200,
      "followingCount": 318,
      "postCount": 604
    },
    "posts": [
      {
        "postId": "3456789012345678901",
        "shortCode": "ExampleCode",
        "caption": "A quick product demo #productreview",
        "takenAtTimestamp": 1787000000,
        "videoDuration": 18.4,
        "isVideo": true,
        "videoPlayCount": 128400,
        "videoViewCount": 128400,
        "likeCount": 6200,
        "commentCount": 184,
        "displayUrl": "https://cdn.example.com/instagram-cover.jpg",
        "videoUrl": "https://cdn.example.com/instagram-video.mp4"
      }
    ],
    "endCursor": "QVFEexample",
    "hasMore": true
  },
  "timestamp": 1787417005
}
```

### Important notes

- Image and carousel posts may not have video views, and list data can omit some engagement fields. Do not interpret missing metrics as poor performance.
- Treat the request as successful only when HTTP is 200 and code is 0. code -1 means no public creator posts were available.
- To generate an AI creator report, turn this response into evidence and send it to /v1/relay/chat/completions.

### Related operations

- [POST /v1/relay/chat/completions](/openapi/operations/createRelayChatCompletion.md)

### Errors

| HTTP | Meaning |
|---:|---|
| 400 | Invalid request parameters or body. |
| 401 | The API key is missing or invalid. |
| 403 | The API key does not have permission for this operation. |
| 429 | Too many requests. Retry with exponential backoff. |
| 500 | Unexpected server error. Retry transient failures with exponential backoff. |


## POST /v1/material/fetch

Operation ID: `fetchPublicVideoData`

Fetch public video data

Fetches public video views and engagement metrics. Supported sources include TikTok, Instagram, Douyin, Xiaohongshu, WeChat Channels, and YouTube.

| Field | Location | Type | Required | Description |
|---|---|---|---:|---|
| `videoUrl` | body | string(uri) | yes | Public http/https URL of the content |

### Request example

```json
{
  "videoUrl": "https://www.tiktok.com/@creator/video/7123456789012345678"
}
```

### Success response

```json
{
  "code": 0,
  "data": {
    "videoId": "7624922739500993822",
    "uniqueId": "creator",
    "playCount": 2109422,
    "diggCount": 143027,
    "commentCount": 1320,
    "shareCount": 36150,
    "collectCount": 17710,
    "coverUrl": "https://cdn.example.com/cover.jpg",
    "videoDesc": "caption #tag",
    "releaseAt": 1775315687
  },
  "message": "success"
}
```

### Errors

| HTTP | Meaning |
|---:|---|
| 400 | Invalid request parameters or body. |
| 401 | The API key is missing or invalid. |
| 403 | The API key does not have permission for this operation. |
| 404 | The public work does not exist or has been deleted. |
| 429 | Too many requests. Retry with exponential backoff. |
| 500 | Unexpected server error. Retry transient failures with exponential backoff. |


## POST /v1/material/analysisTask/stream

Operation ID: `streamViralVideoReplication`

Stream a viral-video replication prompt

Analyzes a public video or an uploaded file and streams a natural-language replication prompt as server-sent events. Use `type: REPLICATION` for viral-video prompt replication. Send either a public `url`, or `businessId` with `businessType` after uploading a local file. Supported public sources include TikTok, Douyin, Xiaohongshu, WeChat Channels, Instagram, YouTube, and Bilibili. Each SSE `data:` line is a JSON object. Concatenate `result` from `status: "streaming"` events in arrival order. If a `status: "done"` event arrives, its `result` is the complete prompt and can replace the assembled chunks. The server may close the stream without a done event. HTTP errors return JSON and no SSE frames.

| Field | Location | Type | Required | Description |
|---|---|---|---:|---|
| `type` | body | REPLICATION | yes | Always send REPLICATION; ANALYSIS is reserved and not covered here |
| `url` | body | string(uri) | conditional | Public video URL; send this or businessId. Supports TikTok, Douyin, Xiaohongshu, WeChat Channels, Instagram, YouTube, and Bilibili |
| `businessId` | body | string | conditional | Uploaded file or material ID; send this or url. Upload a local file first, then pass the fileId as a string |
| `businessType` | body | FILE \| MATERIAL | conditional | Required with businessId; use FILE for uploaded files and MATERIAL for library assets |

### Request example: Replicate from a public video URL

```json
{
  "type": "REPLICATION",
  "url": "https://www.tiktok.com/@creator/video/7123456789012345678"
}
```

### Request example: Replicate from an uploaded file

```json
{
  "type": "REPLICATION",
  "businessId": "591",
  "businessType": "FILE"
}
```

### Stream event: Incremental prompt chunk

```json
{
  "status": "streaming",
  "result": "**Video Script Title**\nA clean product reveal with a slow camera push-in.\n",
  "thinking": null,
  "id": 2066122904659169300
}
```

### Stream event: Completed prompt

```json
{
  "status": "done",
  "result": "**Video Script Title**\nA clean product reveal with a slow camera push-in.\n\n**Characters / Main Subjects**\nA seller presenting a summer product against a bright studio backdrop.\n\n**Scene / Environment**\nBright studio lighting, close-up product shots, and a final call to action.\n\n**Script**\n00:00-00:02 Hook the viewer with the product in hand.\n00:02-00:08 Show the key selling points in short cuts.\n00:08-00:10 End with a clear purchase CTA.\n\n**Notes**\nKeep the pacing tight and preserve the original hook-to-CTA structure.",
  "thinking": null,
  "id": 2066122904659169300
}
```

### Important notes

- A successful response uses Content-Type text/event-stream. Do not judge success by JSON code === 0.
- Each SSE line is data:<json> with status, result, thinking, and a task id. The id stays constant for one request.
- Concatenate result from status=streaming events in arrival order. If status=done arrives, use that result as the complete prompt.
- Failures return a JSON error body instead of SSE. Read the HTTP status and message.
- For a local MP4, call /v1/file/presign and /v1/file/confirm first, then send businessId with businessType=FILE.
- The assembled prompt is usually Markdown with title, subjects, scene, timestamped script, and notes, and can feed AI video generation.

### Related operations

- [POST /v1/file/presign](/openapi/operations/createFileUpload.md)
- [POST /v1/file/confirm](/openapi/operations/confirmFileUpload.md)
- [POST /v1/ai/schedule/create](/openapi/operations/createAiGenerationSchedule.md)

### Errors

| HTTP | Meaning |
|---:|---|
| 400 | Invalid request parameters or body. |
| 401 | The API key is missing or invalid. |
| 403 | The API key does not have permission for this operation. |
| 429 | Too many requests. Retry with exponential backoff. |
| 500 | Unexpected server error. Retry transient failures with exponential backoff. |


## POST /v1/relay/chat/completions

Operation ID: `createRelayChatCompletion`

Relay a chat completion to a supported model

Creates an OpenAI-compatible chat completion with a supported LINGTU relay model. Set `stream: true` to receive SSE chunks. Concatenate `choices[0].delta.content` until the terminal `data: [DONE]` event. Set `stream: false` to receive one JSON completion and read `choices[0].message.content`. Messages may contain plain text or supported image_url content parts.

| Field | Location | Type | Required | Description |
|---|---|---|---:|---|
| `model` | body | string | yes | Supported model identifier available to the current account |
| `messages` | body | RelayChatMessage[] | yes | OpenAI-compatible messages with text and supported image_url content |
| `stream` | body | boolean | no | When true, returns incremental SSE content; defaults to false |
| `max_tokens` | body | integer | no | Maximum output tokens |
| `thinking.type` | body | enabled \| disabled | no | Enable or disable thinking when supported by the selected model |

### Stream event: Incremental model output

```json
{
  "id": "chatcmpl_2066122904659169280",
  "model": "deepseek-v4-flash-vision-exp",
  "choices": [
    {
      "index": 0,
      "delta": {
        "content": "请求已"
      },
      "finish_reason": null
    }
  ]
}
```

### Important notes

- Keep API keys on the server. Never place x-api-key in browser code, logs, or public files.
- With stream=true, parse each data: line and concatenate choices[0].delta.content until data: [DONE].
- Compute usage depends on the selected model, input content, output length, and multimodal inputs such as images.
- image_url must be reachable by the model service; choose an appropriate detail level for the task.

### Errors

| HTTP | Meaning |
|---:|---|
| 400 | Invalid request parameters or body. |
| 401 | The API key is missing or invalid. |
| 403 | The API key does not have permission for this operation. |
| 429 | Too many requests. Retry with exponential backoff. |
| 500 | Unexpected server error. Retry transient failures with exponential backoff. |


## Retry guidance

- Retry network timeouts, HTTP 408, 429, and 5xx responses with exponential backoff.
- Do not blindly retry parameter, permission, or authorization errors.
- Before retrying an object-storage PUT, confirm that the presigned URL is still valid.
- If creating a publishing task times out, check publishing records before creating another task to avoid duplicates.
