Menu

SocialEcho OpenAPI Documentation

SocialEcho OpenAPI Documentation

Last updated: August 28, 2026

1. Scope

This document is intended for developers, QA engineers, implementation teams, and automation engineers integrating with the SocialEcho external API.

It covers teams, accounts, authorization links, posts, reports, OSS uploads, Reddit communities, Pinterest boards, TikTok Shop products and music, and cross-platform publishing through a Team API Key. Brand, AI generation, and document-management APIs are outside the scope of this version.


2. Quick Start

  1. Sign in at https://app.socialecho.net and create a team.
  2. Create a Team API Key in Team Management.
  3. Authenticate with a Bearer token: Authorization: Bearer se_xxx.
  4. Call GET /v1/team first to verify authentication and the team context.
  5. Use the HTTP status code to determine success or failure, then inspect the response code for the specific business result.

3. Environment and Authentication

Field Value
Base URL https://api.socialecho.net
Authentication Bearer Token (Team API Key)
Required header Authorization: Bearer se_your_team_api_key
Optional language header X-Lang: zh_CN or en
Rate limit Maximum 120 requests per minute per API key

3.1 GET Request Rules

Place all business parameters for GET endpoints in the query string. Do not send a request body with a GET request. Use bracketed keys for arrays, for example account_ids[]=1&account_ids[]=2.

CloudFront may return an HTML 403 Bad request response when a GET request contains a body.

3.2 Determining Success

  • Success: HTTP 200-299 and JSON code = 0. All successful endpoints documented here currently return HTTP 200.
  • Failure: HTTP 400-599 and a non-zero business code. Business failures are not returned as HTTP 200.
  • Branch on the HTTP status first, then use code, error.type, and data for detailed handling.
  • For non-2xx responses, still attempt to parse the JSON body and record request_id.
  • A successful publishing response means the job was accepted. It does not mean the destination platform has finished publishing or reviewing the content.

3.3 Standard Response Format

Success:

json Copy
{
  "code": 0,
  "message": "Success",
  "data": {},
  "request_id": "018f7f35-7c9a-7b82-a0f2-6a06b0b7d301"
}

Failure:

json Copy
{
  "code": 42200,
  "message": "Request validation failed",
  "data": {
    "account_id": ["Please select a TikTok Shop account"]
  },
  "error": {
    "type": "invalid_request",
    "reason": "Request validation failed",
    "suggestion": "Check the request parameters and try again"
  },
  "request_id": "018f7f35-7c9a-7b82-a0f2-6a06b0b7d301"
}

The server also returns X-Request-Id in the response headers. A caller may provide a correctly formatted X-Request-Id, or use the server-generated value for request tracing. Paginated success responses also include meta.


4. Error Handling

HTTP status Standard code Meaning and recommended action
400 Bad Request 40000 Invalid request syntax, format, or basic parameters. Correct the request before retrying.
401 Unauthorized 40100 Missing, invalid, or expired API key. Check Authorization: Bearer ....
403 Forbidden 40300 Authenticated but not permitted, such as missing draft permission. Do not retry unchanged.
404 Not Found 40400 The account, product, authorization, or another resource does not exist, is unavailable, or does not belong to the team.
405 Method Not Allowed 40500 Unsupported HTTP method. Use the method shown in the Allow response header.
409 Conflict 40900 The resource state conflicts with the operation. Refresh the resource state before retrying.
413 Payload Too Large 41300 Request body or upload exceeds a server limit. Reduce its size.
419 Authentication Timeout 41900 Session or security token expired. This should not normally occur for Team API Key endpoints.
422 Unprocessable Entity 42200 Field validation, publishing rules, or a recoverable business prerequisite failed. Read field errors in data.
429 Too Many Requests 42900 Rate limit or product-sync cooldown. Prefer Retry-After; otherwise use data.next_allowed_at or the response message.
500 Internal Server Error 50000 Unexpected SocialEcho error. Preserve request_id and contact support.
502 Bad Gateway 50200 Upstream social-platform request failed. Retry later and preserve request_id.
503/504 50300 / 50400 Service unavailable or upstream timeout. Retry with backoff.
Timeout/network error No response body Retry two or three times and retain a snapshot of the request parameters.

Standard business codes use HTTP status x 100. A small number of legacy cases may return a more specific non-zero code; this does not change the HTTP status semantics.

Automatically retry only 429, 502, 503, 504, and network timeouts. Requests returning 400, 401, 403, 404, 405, 409, 413, or 422 usually require a correction to parameters, permissions, or resource state.


5. Endpoints

All examples use https://api.socialecho.net. Replace se_your_team_api_key with your Team API Key.

GET examples intentionally omit Content-Type and a request body. Add parameters directly to the query string.

5.1 Get Team Information (GET /v1/team)

Call this endpoint first to verify the team context.

Parameter Location Required Type Description
X-Lang header No string zh_CN or en; default: zh_CN
bash Copy
curl --request GET 'https://api.socialecho.net/v1/team' \
  --header 'Authorization: Bearer se_your_team_api_key' \
  --header 'Accept: application/json' \
  --header 'X-Lang: en'
json Copy
{
  "code": 0,
  "message": "Success",
  "data": {
    "id": 1024,
    "code": "TEAM_ABC123",
    "title": "SocialEcho QA Team",
    "thumb": "https://oss.socialecho.net/team/TEAM_ABC123/avatar.jpg",
    "describe": "SocialEcho API integration team",
    "created_at": "2026-08-01 02:30:00 UTC",
    "timezone": {
      "id": 45,
      "name": "Asia/Shanghai",
      "offset": "UTC+08:00",
      "city": "Shanghai"
    }
  },
  "request_id": "018f7f35-7c9a-7b82-a0f2-6a06b0b7d301"
}

5.2 List Social Accounts (GET /v1/account)

Parameter Location Required Type Description
X-Lang header No string Response language
page query No integer Page number; the server default applies when omitted
type query No integer 1 = authorized account; 2 = competitor account
bash Copy
curl --request GET 'https://api.socialecho.net/v1/account?page=1&type=1' \
  --header 'Authorization: Bearer se_your_team_api_key' \
  --header 'Accept: application/json' \
  --header 'X-Lang: en'
json Copy
{
  "code": 0,
  "message": "Success",
  "data": [{
    "id": 163751,
    "title": "example_account",
    "account": "example_account",
    "url": "https://www.tiktok.com/@example_account",
    "app": {"id": 11, "title": "TikTokShop"},
    "type": {"value": 1, "label": "Authorized account"},
    "status": {"value": 1, "label": "Active"}
  }],
  "meta": {"total": 1, "current_page": 1, "last_page": 1, "per_page": 15},
  "request_id": "018f7f35-7c9a-7b82-a0f2-6a06b0b7d301"
}

Returns one or more authorization methods for each platform available to the current team. Select a URL by using data[].id, data[].title, and connections[].type. This endpoint has no business parameters.

Parameter Location Required Type Description
Authorization header Yes string Bearer se_your_team_api_key
X-Lang header No string zh_CN or en; default: zh_CN
bash Copy
curl --request GET 'https://api.socialecho.net/v1/oauth/links' \
  --header 'Authorization: Bearer se_your_team_api_key' \
  --header 'Accept: application/json' \
  --header 'X-Lang: en'

Example response, with URLs redacted:

json Copy
{
  "code": 0,
  "message": "Success",
  "data": [
    {
      "id": 1,
      "title": "Instagram",
      "connections": [
        {"type": "instagram", "url": "https://authorization.example/instagram"},
        {"type": "facebook", "url": "https://authorization.example/facebook"}
      ]
    },
    {
      "id": 3,
      "title": "TikTok",
      "connections": [
        {"type": "personal", "url": "https://authorization.example/tiktok"}
      ]
    },
    {
      "id": 11,
      "title": "TikTokShop",
      "connections": [
        {"type": "seller", "url": "https://authorization.example/tiktokshop/seller"},
        {"type": "creator", "url": "https://authorization.example/tiktokshop/creator"}
      ]
    }
  ],
  "request_id": "018f7f35-7c9a-7b82-a0f2-6a06b0b7d301"
}
Field Type Description
data[].id integer Platform ID; corresponds to app.id in the account list
data[].title string Platform name
data[].connections object[] Supported authorization entries
data[].connections[].type string Authorization mode for the platform
data[].connections[].url string URL to open directly; may contain team context or one-time state parameters
Platform Platform ID Connection type
Instagram 1 instagram, facebook
Facebook 2 default
TikTok 3 personal
LinkedIn 4 default
YouTube 5 default
Telegram 6 default
X 7 default
Pinterest 8 personal
Reddit 9 default
Threads 10 personal
TikTokShop 11 seller, creator

Open authorization URLs exactly as returned. Do not rewrite them or remove query parameters. They may contain team-related state and should not be cached long term, publicly shared, or written to ordinary business logs. Request a new URL when authorization is needed.

HTTP status Code Scenario
200 0 Authorization links returned successfully
401 40100 Team API Key is missing, invalid, or expired
405 40500 Incorrect method; use GET
422 42200 Business prerequisite failed, such as insufficient team credits
500 50000 Unexpected server error while generating links

5.4 List Posts (GET /v1/article)

Parameter Location Required Type Description
X-Lang header No string Response language
page query No integer Page number
account_ids query No integer[] Repeat account_ids[] for each account ID
bash Copy
curl --request GET 'https://api.socialecho.net/v1/article?page=1&account_ids[]=163956&account_ids[]=163955&account_ids[]=28' \
  --header 'Authorization: Bearer se_your_team_api_key' \
  --header 'Accept: application/json' \
  --header 'X-Lang: en'
json Copy
{
  "code": 0,
  "message": "Success",
  "data": [{
    "id": 987654,
    "uuid": "platform_post_id",
    "title": null,
    "content": "Example article content",
    "url": "https://www.example.com/post/platform_post_id",
    "app": {"id": 3, "title": "TikTok"},
    "created_at": "2026-08-27 13:00:00 +08:00",
    "updated_at": "2026-08-27 13:05:00 +08:00",
    "account": {
      "id": 163751,
      "avatar": "https://oss.socialecho.net/account/avatar.jpg",
      "account": "example_account",
      "title": "Example Account",
      "url": "https://www.tiktok.com/@example_account"
    },
    "report": {
      "exposure": 1021,
      "like": 40,
      "comment": 14,
      "share": 0,
      "quote": 0,
      "favorite": 12
    },
    "attachments": [{
      "id": 456789,
      "url": "https://oss.socialecho.net/team/TEAM_ABC123/20260827/example.mp4",
      "thumb": null,
      "type": "video",
      "iframe": null
    }],
    "quote": null
  }],
  "meta": {"total": 1, "current_page": 1, "last_page": 1, "per_page": 15},
  "request_id": "018f7f35-7c9a-7b82-a0f2-6a06b0b7d301"
}

5.5 Get Report Data (GET /v1/report)

Parameter Location Required Type Description
X-Lang header No string Response language
start_date query Yes string YYYY-MM-DD; must be earlier than end_date, and the range must not exceed the team's report allowance
end_date query Yes string YYYY-MM-DD; must not be later than today
time_type query Yes integer 1 = posts created in the date range; 2 = all historical posts
account_ids query No integer[] Repeat account_ids[] for each account ID
group query No string Omit for totals; day, app, or account for grouped results
bash Copy
curl --request GET 'https://api.socialecho.net/v1/report?start_date=2026-01-01&end_date=2026-03-24&time_type=1&account_ids[]=163956&account_ids[]=163955&account_ids[]=28' \
  --header 'Authorization: Bearer se_your_team_api_key' \
  --header 'Accept: application/json' \
  --header 'X-Lang: en'

The group value changes the structure of data. Parse the response according to the requested grouping.

Summary response when group is omitted:

json Copy
{
  "code": 0,
  "message": "Success",
  "data": {
    "total": {
      "fans": 5320,
      "content": 84,
      "exposure": 120345,
      "comment": 893,
      "like": 4512,
      "share": 326,
      "quote": 12,
      "favorite": 645
    },
    "increase": {
      "fans": 102,
      "content": 14,
      "exposure": 18340,
      "comment": 116,
      "like": 507,
      "share": 38,
      "quote": 3,
      "favorite": 72
    }
  },
  "request_id": "018f7f35-7c9a-7b82-a0f2-6a06b0b7d301"
}

Abbreviated response for group=day:

json Copy
{
  "code": 0,
  "message": "Success",
  "data": [{
    "date": "2026-03-23",
    "total": {"fans": 5310, "content": 6, "exposure": 8421, "comment": 52, "like": 301, "share": 19, "quote": 1, "favorite": 34},
    "increase": {"fans": 12, "content": 6, "exposure": 8421, "comment": 52, "like": 301, "share": 19, "quote": 1, "favorite": 34}
  }],
  "request_id": "018f7f35-7c9a-7b82-a0f2-6a06b0b7d301"
}

With group=app, each data[] item contains platform id, title, total, and increase. With group=account, each item contains account id, title, account, avatar, url, app, total, and increase. Only day, app, and account are supported grouping values.


5.6 Get an OSS Upload URL (GET /v1/upload/url)

The normal flow is: obtain a presigned upload URL, upload the file using the returned method, then use public_url in publishing attachments.

Parameter Location Required Type Description
X-Lang header No string Response language
content_type query Yes string MIME type of the file; must match the actual file
title query No string File name; maximum 255 characters

Supported content_type values:

  • Images: image/jpeg, image/jpg, image/png, image/gif, image/webp, image/bmp.
  • Videos: video/mp4, video/avi, video/mov, video/wmv, video/flv, video/webm, video/mkv, video/3gp, video/quicktime.
  • Audio: audio/mpeg, audio/mp3, audio/wav, audio/x-wav, audio/aac, audio/mp4, audio/m4a, audio/ogg, audio/webm, audio/flac.
bash Copy
curl --request GET 'https://api.socialecho.net/v1/upload/url?content_type=video%2Fmp4&title=product-video.mp4' \
  --header 'Authorization: Bearer se_your_team_api_key' \
  --header 'Accept: application/json' \
  --header 'X-Lang: en'
json Copy
{
  "code": 0,
  "message": "Success",
  "data": {
    "upload_url": "https://oss.socialecho.net/team/TEAM_ABC123/20260828/AbCdEf1234567890AbCdEf1234567890.mp4?signature=example",
    "method": "PUT",
    "public_url": "https://oss.socialecho.net/team/TEAM_ABC123/20260828/AbCdEf1234567890AbCdEf1234567890.mp4",
    "object_key": "team/TEAM_ABC123/20260828/AbCdEf1234567890AbCdEf1234567890.mp4",
    "headers": {"Content-Type": "video/mp4"},
    "expire_in": 600,
    "file_id": 123456,
    "file": {
      "id": 123456,
      "url": "https://oss.socialecho.net/team/TEAM_ABC123/20260828/AbCdEf1234567890AbCdEf1234567890.mp4",
      "title": "product-video.mp4",
      "extension": "mp4",
      "mime": "video/mp4",
      "type": "video",
      "size": 0,
      "status": "pending",
      "extra": [],
      "created_at": "2026-08-28 10:00:00 +08:00",
      "updated_at": "2026-08-28 10:00:00 +08:00"
    }
  },
  "request_id": "018f7f35-7c9a-7b82-a0f2-6a06b0b7d301"
}

Use the returned method, upload_url, and headers exactly as provided. The signed upload_url expires and must not be modified, cached, or used for publishing.

bash Copy
curl --request PUT 'upload_url_from_previous_response' \
  --header 'Content-Type: video/mp4' \
  --upload-file './product-video.mp4'

After upload, use public_url in the publishing request. Audio upload support does not imply that every publishing platform and type accepts audio attachments.

Success returns HTTP 200 and code = 0. Missing, invalid, or overlong parameters return HTTP 422 and code = 42200. An unexpected error while generating the upload URL returns HTTP 500 and code = 50000. Submit only a MIME type listed above; unsupported MIME types currently return HTTP 500 and code = 50000.


5.7 List Reddit Communities (GET /v1/reddit/communities)

Use this endpoint to select a community before publishing to Reddit.

Parameter Location Required Type Description
X-Lang header No string Response language
account_id query Yes integer Reddit social account ID
bash Copy
curl --request GET 'https://api.socialecho.net/v1/reddit/communities?account_id=163751' \
  --header 'Authorization: Bearer se_your_team_api_key' \
  --header 'Accept: application/json' \
  --header 'X-Lang: en'
json Copy
{
  "code": 0,
  "message": "Success",
  "data": [{
    "id": 301,
    "uuid": "t5_example",
    "title": "example-community",
    "attributes": {
      "description": "Example community",
      "avatar": "https://styles.redditmedia.com/example.png",
      "subscribers": 12000,
      "permissions": {
        "release": true,
        "type": ["text", "media", "link"]
      }
    },
    "created_at": "2026-08-28 10:00:00",
    "updated_at": "2026-08-28 10:00:00"
  }],
  "meta": {"total": 1, "current_page": 1, "last_page": 1, "per_page": 15},
  "request_id": "018f7f35-7c9a-7b82-a0f2-6a06b0b7d301"
}

When publishing to Reddit, use the integer data[].id as extra.category_id, not uuid. Verify attributes.permissions.release = true and that the target post type appears in attributes.permissions.type. The community list does not guarantee flair options. Omit extra.flair when no valid flair has been confirmed; do not submit an empty object.


5.8 List Pinterest Boards (GET /v1/pinterest/boards)

Use this endpoint to select a board before publishing to Pinterest.

Parameter Location Required Type Description
X-Lang header No string Response language
account_id query Yes integer Pinterest social account ID
bash Copy
curl --request GET 'https://api.socialecho.net/v1/pinterest/boards?account_id=163751' \
  --header 'Authorization: Bearer se_your_team_api_key' \
  --header 'Accept: application/json' \
  --header 'X-Lang: en'
json Copy
{
  "code": 0,
  "message": "Success",
  "data": [{
    "id": 401,
    "uuid": "987654321012345678",
    "title": "Home Decor",
    "attributes": {},
    "created_at": "2026-08-28 10:00:00",
    "updated_at": "2026-08-28 10:00:00"
  }],
  "meta": {"total": 1, "current_page": 1, "last_page": 1, "per_page": 15},
  "request_id": "018f7f35-7c9a-7b82-a0f2-6a06b0b7d301"
}

Use the integer data[].id as extra.category_id when publishing. Do not use the platform board uuid.


5.9 List TikTok Shop Products (GET /v1/tiktokshop/products)

Returns products synchronized for a TikTok Shop account. Before publishing a shoppable video or photo post, obtain the complete id, uuid, title, and thumb from this endpoint.

Parameter Location Required Type Description
account_id query Yes integer TikTok Shop account ID from /v1/account
page query No integer Page number; default: 1
per_page query No integer Items per page; 1-100; default: 20
keyword query No string Product-title keyword; maximum 500 characters
bash Copy
curl --request GET 'https://api.socialecho.net/v1/tiktokshop/products?account_id=123456&page=1&per_page=20&keyword=vase' \
  --header 'Authorization: Bearer se_your_team_api_key' \
  --header 'Accept: application/json' \
  --header 'X-Lang: en'
json Copy
{
  "code": 0,
  "message": "Success",
  "data": [{
    "id": 789,
    "uuid": "1732443576158556877",
    "title": "Ceramic Flower Vase",
    "thumb": "https://oss.socialecho.net/team/TEAM_ABC123/20260828/product.jpg",
    "status": 1,
    "price": {"min": "68.88", "max": "68.88", "currency": "USD"}
  }],
  "meta": {"total": 1, "current_page": 1, "last_page": 1, "per_page": 20},
  "request_id": "018f7f35-7c9a-7b82-a0f2-6a06b0b7d301"
}

status = 1 means the product is currently available for publishing. If a localized keyword returns no result, try the product's English title or omit keyword to retrieve all products.

HTTP status Code Scenario
200 0 Product list returned successfully
404 40400 TikTok Shop account does not exist, is unavailable or unauthorized, or does not belong to the team
422 42200 Invalid account_id, pagination, or keyword parameter
500 50000 Unexpected server error while querying products

5.9.1 Submit a TikTok Shop Product Sync (POST /v1/tiktokshop/products/sync)

Requests an asynchronous refresh of products for the account. A successful response means the job entered the queue, not that synchronization has finished. Each account has an approximate 60-minute cooldown.

Parameter Location Required Type Description
account_id body Yes integer TikTok Shop account ID
bash Copy
curl --request POST 'https://api.socialecho.net/v1/tiktokshop/products/sync' \
  --header 'Authorization: Bearer se_your_team_api_key' \
  --header 'Content-Type: application/json' \
  --header 'X-Lang: en' \
  --data-raw '{"account_id":123456}'
json Copy
{
  "code": 0,
  "message": "Product sync job submitted",
  "data": {
    "account_id": 123456,
    "status": "queued"
  },
  "request_id": "018f7f35-7c9a-7b82-a0f2-6a06b0b7d301"
}
HTTP status Code Scenario
200 0 Sync job queued
404 40400 Account does not exist, is unavailable or unauthorized, or does not belong to the team
422 42200 Missing account_id, or account type does not support product synchronization
429 42900 Sync is running or cooling down; wait according to data.next_allowed_at, Retry-After when present, or the response message
500 50000 Failed to submit the sync job; preserve request_id and contact support

5.10 List TikTok Shop Music Genres (GET /v1/tiktokshop/music/genres)

Returns genres supported by the trending-music endpoint. This endpoint has no business parameters.

bash Copy
curl --request GET 'https://api.socialecho.net/v1/tiktokshop/music/genres' \
  --header 'Authorization: Bearer se_your_team_api_key' \
  --header 'Accept: application/json' \
  --header 'X-Lang: en'

Abbreviated response:

json Copy
{
  "code": 0,
  "message": "Success",
  "data": [
    {"value": "ALL", "label": "All"},
    {"value": "POP", "label": "Pop"},
    {"value": "BGM", "label": "Background Music"}
  ],
  "request_id": "018f7f35-7c9a-7b82-a0f2-6a06b0b7d301"
}

Success returns HTTP 200 and code = 0. A business prerequisite such as insufficient credits returns HTTP 422 and code = 42200. Unexpected server errors return HTTP 500 and code = 50000. Authentication and method errors follow Section 4.


Returns available tracks from the TikTok Commercial Music Library. account_id may be an active TikTok Shop account ID or a directly authorized TikTok account ID in the current team. For a TikTok Shop account, the server resolves an associated or available TikTok authorization.

Parameter Location Required Type Description
account_id query Yes integer TikTok Shop or authorized TikTok account ID
country_code query No string Two-letter country code, such as US; default: US
genre query No string Value returned by the genres endpoint; default: ALL
date_range query No string 1DAY, 7DAY, 30DAY, or 90DAY; default: 30DAY
bash Copy
curl --request GET 'https://api.socialecho.net/v1/tiktokshop/music/trending?account_id=123456&country_code=US&genre=BGM&date_range=7DAY' \
  --header 'Authorization: Bearer se_your_team_api_key' \
  --header 'Accept: application/json' \
  --header 'X-Lang: en'
json Copy
{
  "code": 0,
  "message": "Success",
  "data": [{
    "uuid": "6817383821571262465",
    "title": "A lovely acoustic song",
    "artist": "Hiraoka",
    "url": "https://example.tiktokcdn.com/music",
    "cover": "https://example.tiktokcdn.com/cover.jpeg",
    "duration": 81
  }],
  "request_id": "018f7f35-7c9a-7b82-a0f2-6a06b0b7d301"
}
Field Type Description
uuid string Unique music ID; publish it as extra.music.uuid
title string Track title
artist string Artist or performer
url string Audio preview URL
cover string Cover image URL
duration integer Duration in seconds

selection, music_volume, and original_sound_volume are publishing controls and are not returned by the music endpoint. When music is selected, copy all six returned fields (url, uuid, cover, title, artist, and duration) unchanged into extra.music, then add the three publishing controls. Do not submit only a UUID or a reduced four-field object.

Complete music object:

json Copy
{
  "url": "https://sf16-ies-music-sg.tiktokcdn.com/obj/tos-alisg-ve-2102/oUNQD7eSEFCC1sggYZ9DQY0OdArrcwoj6BofBk",
  "uuid": "7231997808928032770",
  "cover": "https://p16-sg.tiktokcdn.com/aweme/100x100/tos-alisg-v-2774/oYHMADhIgAFdBaDftgrjLQoIsFZSsCeZEIpBAa.jpeg",
  "title": "Boundless Worship",
  "artist": "Josué Novais Piano Worship",
  "duration": 715,
  "selection": "trending_clip",
  "music_volume": 50,
  "original_sound_volume": 0
}
HTTP status Code Scenario
200 0 Trending music returned successfully
404 40400 TikTok Shop account does not exist, or no TikTok authorization is available for the music query
422 42200 Invalid account, country, genre, or date range
429 42900 Rate limit reached; retry after Retry-After
502 50200 Upstream TikTok music service failed
500 50000 Other unexpected server error

5.12 Publish a Post (POST /v1/publish/article)

This endpoint publishes across platforms. type, extra, and attachments are platform-specific.

Parameter Location Required Type Description
X-Lang header No string Response language
account_id body Yes integer Social account ID used for publishing
type body Yes string Platform-specific publishing type
status body Yes integer 0 = draft; 1 = publish
scheduled_at body No string Schedule used only when status = 1; omit for immediate publishing. Values without an offset are parsed in the team timezone.
comment body No string or string[] Comments. A string is normalized to an array; clients should send an array. Maximum 10 on supported platforms.
content body Conditional string Main post text; required for some platforms and types
extra body Conditional object Platform-specific fields
attachments body Conditional object[] Platform-specific media list. Each item must include the uploaded file url; a video cover may be supplied as thumb.

Attachment url and thumb must be recognized by the configured SocialEcho OSS. Use the public_url returned by GET /v1/upload/url. The server resolves media type, dimensions, size, duration, and frame rate from OSS; clients do not submit that metadata.

Supported type examples:

  • Facebook: reels, post, stories
  • YouTube: shorts, video
  • Instagram: reels, post, stories
  • X: short_post, long_post
  • LinkedIn: post
  • TikTok: video, photo
  • TikTok Shop: video, photo
  • Pinterest: post
  • Reddit: text, link, media
  • Threads: post
  • Telegram: post

5.12.1 Platform Publishing Reference

The table lists the primary validation rules enforced by the current external publishing endpoint. File limits apply per attachment. Media dimensions, frame rate, duration, and aspect ratio are resolved and validated by the server.

Platform / type content Important extra fields Attachment rules
Facebook reels Optional; max 2,200 characters No required extension fields Exactly 1 video; max 1 GiB; min 540x540; 23-60 fps; 3-300 seconds
Facebook post At least content or media; max 2,200 characters No required extension fields Optional: 1-10 images/GIFs or 1 video; images and video cannot be mixed
Facebook stories Content not supported No required extension fields Exactly 1 image or video; image max 10 MiB; video max 2 GiB
YouTube shorts Required; 1-5,000 characters; max 60 hashtags title required, max 100 characters; tags and containsSyntheticMedia optional Exactly 1 video; max 2 GiB; min 480x480; 1-180 seconds
YouTube video Optional; max 5,000 characters; max 60 hashtags title required, max 100 characters; tags and containsSyntheticMedia optional Exactly 1 video; max 2 GiB; 1-43,200 seconds
Instagram reels Optional; max 2,200 characters and 30 hashtags collaborators optional; max 3 usernames Exactly 1 video; max 300 MiB; 23-60 fps; 3-900 seconds; 9:16
Instagram post Optional; max 2,200 characters and 30 hashtags collaborators optional; max 3 usernames 1-10 images, GIFs, or videos
Instagram stories Content and collaborators not supported No required extension fields Exactly 1 image or video; image max 10 MiB; video max 2 GiB
X short_post Optional; max 280 characters No required extension fields Optional; max 4 images, GIFs, or videos
X long_post Optional; max 25,000 characters No required extension fields Optional; max 4 images, GIFs, or videos
LinkedIn post Optional; max 3,000 characters No required extension fields Optional; max 20 total; up to 20 images/GIFs and up to 1 video
TikTok video Optional; max 2,200 UTF-16 code units draft required boolean; is_ai_generated and music optional; title unsupported Exactly 1 video; max 1 GiB; min 360x360; 23-60 fps; 3-600 seconds
TikTok photo Optional; max 4,000 UTF-16 code units draft required boolean; title optional, max 90 UTF-16 code units; music optional 1-35 jpg, jpeg, or webp images; max 20 MiB each
Pinterest post Optional; max 500 characters category_id required integer from board data[].id; title max 100 characters Exactly 1 image, GIF, or video
Reddit text Required title required, max 300 characters; category_id and flair optional Attachments prohibited
Reddit link Optional title and link required; category_id and flair optional Attachments prohibited
Reddit media Optional title required; category_id and flair optional 1-20 total; up to 20 images/GIFs and up to 1 video
Threads post Optional; max 500 characters No required extension fields Optional; max 20 images or videos; GIF unsupported
Telegram post Optional; max 4,096 characters No required extension fields Optional; max 10 images or videos; comment unsupported

YouTube extra.tags must be an array of strings with no empty values, duplicates, or control characters. The combined length under YouTube's comma-and-quote counting rules must not exceed 500. Supply a YouTube thumbnail through attachments[0].thumb; only jpg, jpeg, and png are supported, with a 2 MiB maximum.

Instagram extra.collaborators must be an array of username strings, with or without a leading @. Usernames may contain only letters, numbers, periods, and underscores, and must not be duplicated. For Reddit, omit extra.flair entirely when it is not needed. When supplied, both uuid and title are required.

bash Copy
curl --request POST 'https://api.socialecho.net/v1/publish/article' \
  --header 'Authorization: Bearer se_your_team_api_key' \
  --header 'Content-Type: application/json' \
  --header 'X-Lang: en' \
  --data @publish-payload.json

5.12.2 Publish TikTok Shop Shoppable Content

Complete these steps before publishing:

  1. Call /v1/account and select an active TikTok Shop account ID.
  2. Call /v1/tiktokshop/products and select the product to attach.
  3. Optionally call the music genres and trending-music endpoints.
  4. Call /v1/upload/url and upload the video or images to OSS.
  5. Publish using the public_url returned by the upload endpoint.

Video publish-payload.json example:

json Copy
{
  "account_id": 123456,
  "type": "video",
  "status": 1,
  "content": "A simple statement piece for every cozy corner. #HomeDecor #TikTokShop",
  "extra": {
    "title": "Minimalist Ceramic Vase",
    "product": {
      "id": 789,
      "uuid": "1732443576158556877",
      "title": "Ceramic Flower Vase",
      "thumb": "https://oss.socialecho.net/team/TEAM_ABC123/20260828/product.jpg"
    },
    "music": {
      "url": "https://sf16-ies-music-sg.tiktokcdn.com/obj/tos-alisg-ve-2102/oUNQD7eSEFCC1sggYZ9DQY0OdArrcwoj6BofBk",
      "uuid": "7231997808928032770",
      "cover": "https://p16-sg.tiktokcdn.com/aweme/100x100/tos-alisg-v-2774/oYHMADhIgAFdBaDftgrjLQoIsFZSsCeZEIpBAa.jpeg",
      "title": "Boundless Worship",
      "artist": "Josué Novais Piano Worship",
      "duration": 715,
      "selection": "trending_clip",
      "music_volume": 50,
      "original_sound_volume": 0
    }
  },
  "attachments": [{
    "url": "https://oss.socialecho.net/team/TEAM_ABC123/20260828/product-video.mp4"
  }],
  "comment": []
}

Replace the illustrative OSS URLs with the public_url returned for the current upload. Product fields must use current values returned by the product-list endpoint.

Photo publish-payload.json example:

json Copy
{
  "account_id": 123456,
  "type": "photo",
  "status": 1,
  "content": "A cozy update for your favorite corner. #HomeDecor #TikTokShop",
  "extra": {
    "title": "Minimalist Ceramic Vase",
    "product": {
      "id": 789,
      "uuid": "1732443576158556877",
      "title": "Ceramic Flower Vase",
      "thumb": "https://oss.socialecho.net/team/TEAM_ABC123/20260828/product.jpg"
    }
  },
  "attachments": [
    {"url": "https://oss.socialecho.net/team/TEAM_ABC123/20260828/product-1.jpg"},
    {"url": "https://oss.socialecho.net/team/TEAM_ABC123/20260828/product-2.jpg"}
  ],
  "comment": []
}

TikTok Shop common requirements:

  • account_id must identify an active TikTok Shop account belonging to the current team.
  • type supports only video or photo.
  • extra.title is required, with a maximum of 30 characters. It supports Unicode letters, digits, and spaces only; punctuation is not allowed.
  • extra.product is required. Copy id, uuid, title, and thumb directly from the product-list response.
  • The product must be available: the product-list response must contain status = 1.
  • extra.music is optional. When music is selected, include all nine fields: url, uuid, cover, title, artist, duration, selection, music_volume, and original_sound_volume.
  • Copy url, uuid, cover, title, artist, and duration unchanged from the current music-query result. Do not construct, truncate, or reduce the object to a UUID.
  • extra.music.selection supports none, trending_clip, and full_track. A complete music object is required when the value is not none.
  • music_volume and original_sound_volume must be integers from 0 to 100; the example uses 50 and 0.
  • When no music is selected, omit extra.music or send {"selection":"none"}.
  • status = 1 without scheduled_at submits the post immediately.

TikTok Shop video requirements:

  • content is required and must not exceed 2,200 UTF-16 code units.
  • Exactly one video is supported, with a maximum size of 500 MB.
  • Supported formats: mp4, mov, mkv, wmv, webm, avi, 3gp, flv, mpeg, and mpg. Files of 10 MiB or more should use mp4, mov, or webm.
  • extra.is_ai_generated is an optional boolean.

TikTok Shop photo requirements:

  • content is optional and must not exceed 5,000 UTF-16 code units when supplied.
  • attachments must contain at least one image and images only. The current API does not impose an image-count maximum, but TikTok Shop platform limits still apply.
  • Supported formats: jpg, jpeg, png, webp, heic, and bmp. Each image must be larger than zero and no larger than 10 MiB.
  • Image dimensions must be readable and each aspect ratio must be between 9:16 and 16:9.
json Copy
{
  "code": 0,
  "message": "Submitted successfully",
  "data": {"id": 183308},
  "request_id": "018f7f35-7c9a-7b82-a0f2-6a06b0b7d301"
}

data.id is the SocialEcho publishing-record ID. HTTP 200 with code = 0 means the job was submitted; it does not mean TikTok Shop has completed publishing. Platform processing and review are asynchronous.

HTTP status Code Scenario
200 0 Publishing job submitted
403 40300 Team lacks draft permission when status = 0
404 40400 Team, account, or linked resource does not exist, or account does not belong to the team
422 42200 Field, attachment, product, music, TikTok Shop rule, business prerequisite, or recoverable runtime validation failed
500 50000 Other unexpected server error

The asynchronous job is submitted after the publishing record is created. Therefore, an HTTP 422 or 500 during submission does not guarantee that no record was created. Do not immediately repeat the request. Preserve request_id, check the post list or back-office record, and retry only after confirming that no corresponding record exists.


6. Integration Recommendations

  1. Retrieve the account list first, then use account_id for post, report, material-query, and publishing endpoints.
  2. For paginated endpoints, increment page until meta.current_page >= meta.last_page.
  3. In n8n, Zapier, Dify, and similar workflow tools, separate authentication, validation, rate-limit, and upstream-platform failure branches.
  4. Log the request time, endpoint, HTTP status, business code, request_id, and key request parameters for troubleshooting.
  5. For publishing, upload media through GET /v1/upload/url before assembling attachments.
  6. Always use the complete, current product object returned by the product-list endpoint for TikTok Shop publishing.
  7. Trending music can vary by country, genre, and date range. Query it immediately before publishing.
  8. Keep all automation below 120 requests per minute per API key and use exponential backoff for 429, 502, and network timeouts.

7. Frequently Asked Questions

Q1: How do I determine whether a request succeeded?

Only HTTP 2xx with JSON code = 0 is successful. HTTP 4xx/5xx is a failure, but parse the response for code, error, data, and request_id. Treat HTTP 2xx with a non-zero code as a contract anomaly and record request_id.

Q2: How do I pass account_ids in the query string?

Repeat the bracketed key: account_ids[]=163956&account_ids[]=163955&account_ids[]=28.

Q3: How do I avoid HTTP 429?

Keep each API key below 120 requests per minute and implement throttling with exponential backoff. Prefer Retry-After; for product-sync cooldowns without that header, use data.next_allowed_at or the response message.

Q4: How do I confirm that an account is a TikTok Shop account?

Call /v1/account, verify app.title = "TikTokShop", and confirm status.value = 1.

Q5: Why does a product keyword return no results?

Some product titles are in English. Try the English title or omit keyword to retrieve all products and filter them locally.

Q6: Why is a new video not visible on TikTok immediately after the publishing request succeeds?

Success means the job was submitted. Upload, platform processing, and review are asynchronous. Save the publishing-record ID and request_id for troubleshooting.

Q7: What is the difference between upload_url and public_url?

upload_url is a temporary presigned OSS URL used only to upload the file. Use public_url as attachments[].url in the publishing request.

Q8: Why does the music endpoint not return volume fields?

The trending-music endpoint returns six media fields: url, uuid, cover, title, artist, and duration. Copy all six unchanged to extra.music, then add selection, music_volume, and original_sound_volume, for nine fields total. To play only the selected music on a TikTok Shop video, use music_volume = 50 and original_sound_volume = 0.

Q9: Should Pinterest boards and Reddit communities use id or uuid when publishing?

Use the integer data[].id as extra.category_id. uuid is the platform resource identifier, not the publishing category ID. Reddit flair is separate: when required, send both extra.flair.uuid and extra.flair.title.

Q10: Is an attachment url sufficient?

Yes. Each attachments[] item needs at least the public_url returned by the current OSS upload. Add thumb when a custom video cover is needed. The server fills in media type, size, dimensions, duration, and frame rate from OSS. External CDN URLs, upload_url, expired signed URLs, and URLs outside the configured SocialEcho OSS fail validation.


This document applies to SocialEcho OpenAPI v1, revised August 28, 2026. Build requests according to these fields and examples, and recheck platform publishing limits whenever the document version changes.

Previous
API Documentation
Next
Affiliate Reward
Last modified: 2026-08-28Powered by