Skip to main content

tiktok-shop-api: TikTok Shop API client for Python

A typed Python client for the TikTok Shop API (the TikTok Shop Partner API). It covers over 300 operations across orders, products, fulfillment, logistics, finance, affiliate, customer service and more, with a sync client and an async client.

It signs requests for you, handles OAuth, works with many shops at once, and verifies and types TikTok Shop webhooks.

Unofficial. Not affiliated with or endorsed by TikTok or ByteDance.

Request signing follows TikTok's documentation and has not been verified against the live API. If TikTok rejects a signature, please open an issue at https://github.com/isaackogan/TikTok-Shop-Api-SDKs/issues.

The client is generated from an OpenAPI spec that is itself built from the TikTok Shop Partner Center docs: tiktok-shop.openapi.yaml.

Install

pip install tiktok-shop-api

Requires Python 3.11 or newer. Its dependencies are httpx and attrs.

OAuth: get an access token

import os

from tiktok_shop_api import TikTokShopAuth

code_from_redirect = "the ?code= value from your redirect URL"

auth = TikTokShopAuth(
    os.environ["TTS_APP_KEY"],
    os.environ["TTS_APP_SECRET"],
    service_id=os.environ["TTS_SERVICE_ID"],  # seller and partner flows
)

# 1. Send the seller here. `type` is "seller", "partner" or "creator"; `region` is "us" or "row".
url = auth.authorization_url(type="seller", region="us", state="csrf-token")

# 2. TikTok redirects back with ?code=...; exchange it.
tokens = auth.exchange_code(code_from_redirect)
# tokens.access_token, tokens.refresh_token, tokens.open_id, tokens.granted_scopes, ...

# 3. Before the access token expires (access_token_expire_in is a Unix timestamp):
renewed = auth.refresh(tokens.refresh_token)

AsyncTikTokShopAuth has the same methods as coroutines. A non-zero code in TikTok's response raises a TikTokShopError with code, message and request_id (see Errors).

Make your first call

import os

from tiktok_shop_api import TikTokShop

access_token = os.environ["TTS_ACCESS_TOKEN"]

with TikTokShop(os.environ["TTS_APP_KEY"], os.environ["TTS_APP_SECRET"], access_token=access_token) as client:
    # Find the shop cipher
    shops = client.authorization.get_authorized_shops()
    assert shops is not None
    shop_cipher = shops.to_dict()["data"]["shops"][0]["cipher"]

    seller = client.with_shop(access_token=access_token, shop_cipher=shop_cipher)
    orders = seller.orders.get_order_list(page_size=20)

The async client mirrors it, with await on every call:

import asyncio
import os

from tiktok_shop_api import AsyncTikTokShop

access_token = os.environ["TTS_ACCESS_TOKEN"]


async def main() -> None:
    async with AsyncTikTokShop(os.environ["TTS_APP_KEY"], os.environ["TTS_APP_SECRET"], access_token=access_token) as client:
        shops = await client.authorization.get_authorized_shops()
        assert shops is not None
        seller = client.with_shop(shop_cipher=shops.to_dict()["data"]["shops"][0]["cipher"])
        orders = await seller.orders.get_order_list(page_size=20)


asyncio.run(main())

One attribute per API area hangs off the client (orders, products, fulfillment, finance, affiliate_seller, and so on). Every call is signed, timestamped and sent with your access token. The shop_cipher query parameter is added for you on the endpoints that need it.

Many shops

with_shop returns a client for another shop. It shares the HTTP transport and your app credentials, so you can keep one per shop. Arguments you leave out keep the original's values, and the original is never changed:

import os

from tiktok_shop_api import TikTokShop

client = TikTokShop(os.environ["TTS_APP_KEY"], os.environ["TTS_APP_SECRET"])
token_a, cipher_a = os.environ["TOKEN_A"], os.environ["CIPHER_A"]
token_b, cipher_b = os.environ["TOKEN_B"], os.environ["CIPHER_B"]

shop_a = client.with_shop(access_token=token_a, shop_cipher=cipher_a)
shop_b = client.with_shop(access_token=token_b, shop_cipher=cipher_b)

Webhooks

Verify the signature against the raw request body, then parse it into a typed event. This example uses Flask; any framework that gives you the unmodified bytes works:

import os

from flask import Flask, request

from tiktok_shop_api import UnknownWebhookEvent, WebhookSignatureError, Webhooks
from tiktok_shop_api.generated.models import OrderStatusChangeWebhook

app = Flask(__name__)


@app.post("/webhooks/tiktok-shop")
def tiktok_shop_webhook():
    try:
        event = Webhooks.verify_and_parse(
            app_key=os.environ["TTS_APP_KEY"],
            app_secret=os.environ["TTS_APP_SECRET"],
            raw_body=request.get_data(),  # exactly as received
            signature=request.headers.get("Authorization", ""),
        )
    except WebhookSignatureError:
        return "", 401
    except ValueError:  # not a webhook this SDK can read
        return "", 400
    if isinstance(event, UnknownWebhookEvent):
        print("unknown webhook type", event.type, event.raw)
    elif isinstance(event, OrderStatusChangeWebhook):
        print(event.shop_id, event.data)
    return "", 200
  • Never re-serialize the body before verifying. Changed whitespace or key order makes the signature fail.
  • A webhook type this SDK does not know comes back as UnknownWebhookEvent(type, raw). Known events are the generated model for that webhook, so isinstance narrows them.
  • Parsing is strict. parse raises ValueError for a body that is not a JSON object, a type that is missing or not an integer, or a known type with a required field missing or null: a known type missing a required field is a parse error.
  • EVENT_TYPES maps a type number to its name (1 is ORDER_STATUS_CHANGE).

Options

  • base_url (on the clients and the auth helpers) must be an origin such as https://host:8443, with no path prefix: signing and shop-cipher matching use the request path.
  • timeout (on all four) is in seconds and defaults to 30. None or 0 means no limit; you can also pass an httpx.Timeout.
  • Requests carry the User-Agent tiktok-shop-api-python/<version>.
  • Token calls send app_secret, auth_code and refresh_token in the URL query, and httpx logs every request URL at INFO. Importing tiktok_shop_api adds a filter to the httpx logger that replaces those three values with ***, so a service logging at INFO never writes them. Keep the filter if you reconfigure that logger.

Errors

Every failed call raises TikTokShopError, with code, message, request_id, http_status and the original exception as __cause__:

What happened code http_status
TikTok's reply has a non-zero code, even on HTTP 200 TikTok's code the status
A non-2xx reply TikTok's non-zero code if the body has one, else the HTTP status the status
A 2xx reply that can't be read: not a JSON object, a code that isn't an integer, a body that doesn't fit its model, or a token reply without data -1 the status
No HTTP response at all: connection refused, DNS, TLS, or a timeout -1 None

About

This is the Python package of a set of generated TikTok Shop API SDKs. The OpenAPI spec and the other languages live in isaackogan/TikTok-Shop-Api-SDKs.

MIT licensed. Unofficial. Not affiliated with or endorsed by TikTok or ByteDance.

Metadata

Release files for tiktok-shop-api 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for tiktok-shop-api 0.1.0
File Size Uploaded Provenance
tiktok_shop_api-0.1.0.tar.gz 1.3 MB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for tiktok-shop-api 0.1.0
File Interpreter ABI Platform
tiktok_shop_api-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 4.9 MB

Release files / tiktok_shop_api-0.1.0.tar.gz

Download URL tiktok_shop_api-0.1.0.tar.gz
Size 1.3 MB
Tags Source
SHA-256 checksum
How to use checksums
7289dc90b3768eeb110582da17050b7310a56a341d52d7b5a8801d6a2ea2b1f6
BLAKE2b-256 checksum
How to use checksums
f5d48df8169bbd26392cc611961341f67dae572468098cde3483452ea25bda14
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.

Transparency log

Release files / tiktok_shop_api-0.1.0-py3-none-any.whl

Download URL tiktok_shop_api-0.1.0-py3-none-any.whl
Size 3.6 MB
Tags Python 3
SHA-256 checksum
How to use checksums
ff5d5082458da8bfb16bb925a87377b1777107ebb4e1f1491b4a8faee52d032d
BLAKE2b-256 checksum
How to use checksums
398426b6861496c2b26b28d1fc5c05ef7bbf72fcea22d9a6f89555ffb4cdc525
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.

Transparency log

Security for tiktok-shop-api 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for tiktok_shop_api-0.1.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page