Skip to main content
Glama
tokportal

tokportal-mcp

Official
by tokportal
README.md
# tokportal

[![PyPI](https://img.shields.io/pypi/v/tokportal.svg)](https://pypi.org/project/tokportal/)
[![Python](https://img.shields.io/pypi/pyversions/tokportal.svg)](https://pypi.org/project/tokportal/)
[![license](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)

TokPortal is the managed social infrastructure API: real TikTok, Instagram and YouTube accounts created, warmed and operated by human account managers in 16+ countries — exposed as a REST API and an MCP server. No OAuth per account, no 25-posts/day cap, no app review.

Docs https://developers.tokportal.com · API base https://app.tokportal.com/api/ext · OpenAPI https://developers.tokportal.com/openapi.json · MCP remote https://app.tokportal.com/api/ext/mcp · Get an API key https://app.tokportal.com/developer/api-keys?utm_source=pypi&utm_medium=readme&utm_campaign=tokportal-python · llms.txt https://developers.tokportal.com/llms.txt

---

`tokportal` is the official Python SDK for the TokPortal API (Python 3.9+, typed, standard library only). Every public operation is available as a resource method or through the generated `request_operation` map.

## Install

```bash
pip install tokportal
```

## 30-second quickstart

```python
import os
from tokportal import TokPortal

client = TokPortal(api_key=os.environ["TOKPORTAL_API_KEY"])

# 1. Create a bundle: a fresh managed TikTok account in the USA + 1 video slot.
#    Credits are debited now; the account manager is assigned at publish time.
bundle = client.bundles.create({
    "bundle_type": "account_and_videos",
    "platform": "tiktok",
    "country": "USA",
    "title": "US launch",
    "videos_quantity": 1,
})
bundle_id = bundle["data"]["id"]

# 2. Upload the video straight from disk -> public_url
upload = client.uploads.video_direct("./launch.mp4", bundle_id, content_type="video/mp4")

# 3. Configure the account profile and video slot 1, then publish
client.bundles.configure_account(bundle_id, {
    "username": "mybrand.us",
    "visible_name": "My Brand",
    "biography": "Official account",
})
client.bundles.configure_video(bundle_id, 1, {
    "video_type": "video",
    "video_url": upload["data"]["public_url"],
    "description": "Day 1 - launching in the US #launch",
    "target_publish_date": "2026-09-01",
})
client.bundles.publish(bundle_id)

# 4. Later (webhook `account.in_review` / `account.finalized`, or polling):
#    saved_account_id is the real delivered account -> read it back
current = client.bundles.get(bundle_id)["data"]
if current.get("saved_account_id"):
    account = client.accounts.get(current["saved_account_id"])["data"]
    print(account["username"], account["profile_url"])
```

> Method names follow the generated resource map (`bundles`, `uploads`, `accounts`, `analytics`, `webhooks`). If a helper does not exist for an operation, use `client.request_operation("<operationId>", path=..., query=..., body=...)`.

## Full example

```python
import os
from tokportal import TokPortal, TokPortalApiError

client = TokPortal(api_key=os.environ["TOKPORTAL_API_KEY"])

me = client.me()

bundle = client.bundles.create({
    "bundle_type": "account_and_videos",
    "country": "USA",
    "videos_quantity": 5,
})

csv = client.analytics.export_videos(account=["saved-account-id"])
image = client.uploads.image_from_url({
    "url": "https://cdn.example.com/photo.jpg",
    "bundle_id": bundle["data"]["id"],
})

print(me["data"]["email"], bundle["data"], csv, image["data"])
```

Direct multipart uploads use the same structured errors and idempotency support:

```python
uploaded = client.uploads.video_direct(
    "./video.mp4",
    bundle["data"]["id"],
    content_type="video/mp4",
    idempotency_key="video-upload-123",
)
```

Manage TokPortal Coverage from the latest atomic quote. A zero-credit quote is
valid and still requires an explicit reactivation call:

```python
coverage = client.accounts.coverage("saved-account-id")
quote = coverage["data"]["reactivation_quote"]

if quote:
    client.accounts.reactivate_coverage(
        "saved-account-id",
        {
            "expected_credits": quote["credits"],
            "expected_current_period_end": quote["current_period_end"],
            "expected_lock_version": quote["lock_version"],
        },
        idempotency_key="coverage-reactivate-saved-account-id-v4",
    )

client.accounts.pause_coverage(
    "saved-account-id",
    idempotency_key="coverage-pause-saved-account-id-v4",
)
```

Credential reveal and verification-code access use the same irreversible
two-step policy flow. First call without acceptance to receive HTTP 428 and
`error.details.policy_version`; then show those terms to the account owner and
retry with that exact version. The accepted request may debit credits and
permanently detach the account. These secret-bearing responses are never stored
for replay, so these helpers intentionally do not accept `idempotency_key`.
After an uncertain transport result, reconcile the safe account state before
deciding whether to call the endpoint again without a key:

If an accepted call returns HTTP 409 with
`CREDENTIAL_REVEAL_QUOTE_CHANGED`, no charge or reveal occurred. Read the
current policy and `expected_credit_cost` from `error.details`, show the new
terms to the owner, obtain fresh consent, and retry with the new version. Never
retry a 409 automatically.

```python
try:
    client.accounts.reveal_credentials("saved-account-id")
except TokPortalApiError as error:
    if error.status_code != 428:
        raise

    policy_version = str(error.details["policy_version"])
    credentials = client.accounts.reveal_credentials(
        "saved-account-id",
        acceptance={
            "acknowledge_support_forfeit": True,
            "policy_version": policy_version,
        },
    )
```

The same no-replay rule applies to `webhooks.create`, `uploads.image`,
`uploads.video`, and `analytics.create_report` because they return a signing
secret, signed upload capability, or report access token. These helpers do not
accept `idempotency_key`, and `request_operation` rejects one locally for all
six sensitive operation IDs.

Discover and operate webhooks without dropping to raw HTTP:

```python
catalog = client.webhooks.events()
endpoints = client.webhooks.list(event="bundle.published")
retry = client.webhooks.retry_delivery(endpoints["data"][0]["id"], "delivery-id")
```

Every OpenAPI operation is also reachable through the generated operation map:

```python
same_retry = client.request_operation(
    "retryWebhookDelivery",
    path={"id": endpoints["data"][0]["id"], "delivery_id": "delivery-id"},
)

csv_again = client.request_operation(
    "exportAnalyticsVideos",
    query={"account": ["saved-account-id"]},
)
```

The SDK sends `X-TokPortal-Client: tokportal-python/0.1.0` on API requests for observability and support diagnostics.

Verify signed webhook deliveries with the exact raw request body:

```python
from tokportal import verify_webhook_signature

valid = verify_webhook_signature(
    raw_body,
    request.headers["TokPortal-Signature"],
    os.environ["TOKPORTAL_WEBHOOK_SECRET"],
)
```

```python
from tokportal import TokPortalApiError

try:
    client.bundles.create({
        "bundle_type": "account_and_videos",
        "country": "USA",
        "videos_quantity": 5,
    })
except TokPortalApiError as error:
    print(error.status_code, error.code, error.details, error.request_id)
    if error.retryable:
        wait_seconds = error.retry_after_seconds or 1
        # Retry with backoff.
        pass
    print(error.rate_limit)
```

API keys use the format `sk_` followed by 64 lowercase hex characters. TokPortal stores only a SHA-256 hash of the key and shows the raw key once at creation.

## Source of truth

This package is generated from the TokPortal public OpenAPI schema
(https://developers.tokportal.com/openapi.json) in the private TokPortal
monorepo. Generated files (`tokportal/_generated.py`) are overwritten on every release — do not edit
them by hand. See [CONTRIBUTING.md](./CONTRIBUTING.md) for what we accept as PRs
and [SECURITY.md](./SECURITY.md) for vulnerability reporting.

## Links

- Documentation: https://developers.tokportal.com
- SDKs & CLI guide: https://developers.tokportal.com/sdks-cli
- MCP server: https://developers.tokportal.com/mcp · [`tokportal-mcp`](https://www.npmjs.com/package/tokportal-mcp)
- API reference (OpenAPI): https://developers.tokportal.com/openapi.json
- Other packages: [`@tokportal/node`](https://www.npmjs.com/package/@tokportal/node) · [`@tokportal/cli`](https://www.npmjs.com/package/@tokportal/cli) · [`tokportal` (PyPI)](https://pypi.org/project/tokportal/) · [`github.com/tokportal/tokportal-go`](https://github.com/tokportal/tokportal-go)

MIT © TokPortal

TDQS

B3.1/5.0

Scored across 91 tools

Disambiguation3/5

Many tools exist (91), and while descriptions are detailed, overlapping categories like analytics (16 tools) and multiple account-related operations can confuse an agent. Tools such as tokportal_get_analytics_series, tokportal_get_analytics_account, and tokportal_get_account_analytics have similar purposes despite different scopes, increasing misselection risk.

Naming Consistency5/5

All tools follow the tokportal_verb_noun pattern with snake_case. Verbs like list, get, create, update, delete, publish, configure are used consistently. Minor deviations like tokportal_can_refresh_account_analytics and tokportal_fix_bundle_video_download are still clear and fit the pattern. Excellent consistency.

Tool Count1/5

91 tools is extremely high for a single MCP server. This scoping seems excessive; the functionality could be split into multiple focused servers (e.g., analytics, bundles, accounts, webhooks). The count far exceeds typical well-scoped servers (3-15 tools) and hinders agent efficiency.

Completeness4/5

The tool set covers the full lifecycle of TokPortal operations: account management, bundles, video slots, analytics, comment tasks, webhooks, uploads, and subscriptions. There are no obvious major gaps. Minor missing features (e.g., deleting analytics reports) might exist but core workflows are well-covered.

Maintenance

ActivityMaintained
ResponsivenessNo issues