Comments
Schedule comments from your delivered TokPortal accounts on third-party social videos. Comments are posted by the account manager assigned to each account, then auto-verified by scraping the target video's comment list.
POST /api/ext/comments Create one or many comment tasks
GET /api/ext/comments List your comment tasks (paginated)
GET /api/ext/comments/{id} Read one task with full state
DELETE /api/ext/comments/{id} Cancel a pending task (refund 1 credit)
POST /api/ext/comments/{id}/approve Approve a manually-confirmed task
POST /api/ext/comments/{id}/dispute Dispute a manually-confirmed task
GET /api/ext/comments/{id}/verifications Verbose verifier timeline
Pricing
1 credit per comment task — debited up-front when the task is created. Refunded automatically if:
- the row is rejected at validation time (e.g. invalid URL, account not yours)
- you cancel a
pendingtask viaDELETE /api/ext/comments/{id} - the 72-hour hard deadline expires before the manager posts (auto-cancellation)
The CM payout is paid out of TokPortal funds — it does not affect your credit balance.
Supported platforms
| Platform | Comment posting | Auto-verification | Comment max length |
|---|---|---|---|
| TikTok | ✅ | ✅ | 150 chars |
| ✅ | ✅ | 2,200 chars | |
| YouTube | ❌ (coming) | ❌ | — |
Auto-verification scrapes up to 100 of the target video's most recent comments and matches them by author handle + text similarity (Sørensen-Dice ≥ 0.95).
Lifecycle
A task moves through these states. Statuses surface verbatim in GET /api/ext/comments/{id} so your code can branch on them.
| Status | Meaning | Visible in API |
|---|---|---|
pending | Awaiting the account manager to post the comment. Hard deadline: 72h. | ✅ |
submitted | Manager declared they posted. Auto-verifier ran with a 30s grace window — still not matched. The CM should either retry (if a propagation lag) or manual-confirm. | ✅ |
verified_auto | Auto-verifier matched the comment on the target video. Payout locked in 24h (auto-finalize). | ✅ |
manually_confirmed | Auto-verification couldn't find the comment; manager swore they posted. You have 72 hours to approve or dispute. After that, payout auto-locks. | ✅ |
pending_corrections | The manager is fixing something you disputed. Hidden if it was an auto-detected issue (the manager is fixing it before you ever see it). | ✅ (only client-disputed) |
finalized | Payout was locked, manager wallet credited. Terminal state. | ✅ |
cancelled | Cancelled by you (DELETE) or by the 72h expiry sweep. Credit refunded. | ✅ |
rejected / needs_review | Internal — should never appear via the API. | hidden |
Lifecycle diagram (happy path)
create
│
▼
pending ─── manager posts ───► submitted
│
┌─── verifier matches ▼ ────┐
│ │
▼ ▼
verified_auto manually_confirmed
│ │
│ (24h auto-finalize) │ you approve ───► finalized
▼ │ you dispute ───► pending_corrections
finalized │ 72h pass ───► finalized (auto)
▼
─ pending_corrections
│ manager fixes + retries verify
▼
verified_auto / manually_confirmed
Error handling
All endpoints return a uniform error envelope:
{
"error": {
"code": "COMMENT_PLATFORM_MISMATCH",
"message": "The video URL's platform does not match the account's platform...",
"details": { "account_platform": "tiktok", "url_platform": "instagram" }
}
}
Comment-specific error codes
| Code | HTTP | Trigger |
|---|---|---|
COMMENT_TASK_NOT_FOUND | 404 | Task ID doesn't exist or doesn't belong to your account. |
COMMENT_TASK_NOT_OWNED | 403 | Task exists but belongs to another user. |
COMMENT_INVALID_STATUS | 409 | Action not allowed in current status (e.g. cancel a finalized task). |
COMMENT_ACCOUNT_NOT_MANAGED | 409 | The target account has no current_cm_id. Wait for an order to be in progress. |
COMMENT_PLATFORM_MISMATCH | 400 | Video URL platform ≠ account platform. |
COMMENT_INVALID_VIDEO_URL | 400 | Could not parse the video URL. |
COMMENT_TEXT_TOO_LONG | 400 | comment_text exceeds the platform's character limit. |
COMMENT_TEXT_EMPTY | 400 | comment_text is blank. |
COMMENT_DISPUTE_REASON_REQUIRED | 400 | Dispute call missing or short reason field. |
INSUFFICIENT_CREDITS | 402 | Not enough credits for the requested batch. |
SAVED_ACCOUNT_NOT_FOUND | 404 | saved_account_id doesn't match any of your accounts. |
SAVED_ACCOUNT_NOT_OWNED | 403 | Account belongs to someone else. |
When creating a batch, the response always succeeds at HTTP-201 even if individual rows are rejected. Inspect created / rejected to surface per-row results.
Batch behaviour vs single-shot
The POST /api/ext/comments body accepts either a single object or { "tasks": [...] }. The two paths differ in error semantics:
- Single object → if the row is rejected at validation, the endpoint returns the matching
400/409/404error code. Easier to detect failure. - Batch (
tasks: [...]) → always returns201with arejectedarray even if every row fails. The batch is partial-success — the rows that pass are still created.
What auto-verification actually checks
The verifier runs once, 30 seconds after the manager clicks "I posted it" (so the platform has time to index the new comment). It then:
- Scrapes the target video's last ~100 comments via Apify.
- Filters to comments whose author handle matches the saved account.
- Computes Sørensen-Dice text similarity vs your
comment_text. - Decides:
- ≥ 0.95 + same handle →
verified_auto - < 0.95 + same handle (text drifted) →
pending_corrections, manager is asked to edit/repost - ≥ 0.92 + different handle (text matches but wrong account) →
pending_corrections, manager asked to delete + repost from the right account - nothing matches → manager is offered the manual confirmation modal, which moves the task into
submitted(still in flight) ormanually_confirmed(your turn)
- ≥ 0.95 + same handle →
You can fetch the full verifier timeline via GET /api/ext/comments/{id}/verifications.
Rate limits & quotas
- API rate limit: 120 req/min per key (shared with the rest of the TokPortal API).
- Batch size cap: 200 tasks per
POSTbody. - Hard deadline per task: 72 hours between creation and
submitted. Tasks that expire are auto-cancelled and credits refunded.