Guides / End-to-end tutorials / SMM multi-account runner A–Z

SMM multi-account runner A–Z

Bind caller-owned brand, agency, UGC and theme-page accounts to sticky 1:1 mobile device + city contexts, run realistic multi-day organic warming and foreground lifecycle loops, brand profiles, precheck & publish media, and convert comment/DM leads.

1. Sticky 1:1 device contexts, lifecycle hygiene & multi-day warming

Most SMM automation fails because operators fire raw upload calls from cold sessions or shared datacenter footprints without mobile foreground telemetry. Every Connected Workspace account on Tikultra is pinned 1:1 to a dedicated FullPool Android or iOS context in one city (miami, london, los_angeles). Before publishing on a newly imported session, run 2–3 daily foreground sessions (session/warm-reopen → warm/niche + warm/seed-accounts + warm/watch-item → session/tick → session/background) so TikTok’s interest graph and trust signals match a real niche user.

ActionEndpointCost
Import sessionPOST /v1/account/import25 cr
Email sign-in: send codePOST /v1/account/login/otp/send25 cr
Session healthGET /v1/account/health15 cr
Warm reopen lifecyclePOST /v1/account/session/warm-reopen15 cr
Warm session for nichePOST /v1/account/warm/niche25 cr
Warm from seed creatorsPOST /v1/account/warm/seed-accounts25 cr
Watch item telemetryPOST /v1/account/warm/watch-item15 cr
Update profilePOST /v1/account/profile/update25 cr
Upload precheckGET /v1/account/upload/precheck15 cr
Publish videoPOST /v1/account/upload/video100 cr
InboxGET /v1/account/dm/inbox20 cr
Send messagePOST /v1/account/dm/send35 cr

2. Runnable daily SMM fleet loop (warm → brand → precheck → publish → DM)

TypeScript SDKPython SDKMCP / cURLsmm_account_runner
1import { TikUltra } from 'tikultra'
2
3const client = new TikUltra({ apiKey: process.env.TIKULTRA_KEY, os: 'ios', appFlavour: 'tiktok', region: 'US', city: 'miami' })
4
5export async function runDailySmmCycle(accountId: string, videoUrl?: string) {
6  // 1. Verify session health & sticky device context before mutating
7  const health = await client.account.health(accountId)
8  if (health.data.restricted || health.data.status === 'expired') {
9    throw new Error(`Session ${accountId} requires attention: ${JSON.stringify(health.data)}`)
10  }
11
12  // 2. Foreground resume + organic niche, seed-creator & watch-dwell telemetry
13  await client.account.warmReopen(accountId)
14  await client.account.warmNiche({ account_id: accountId, niche: 'b2b saas', duration_sec: 45, like_items: true })
15  await client.account.warmSeedAccounts({ account_id: accountId, usernames: ['linear', 'vercel', 'raycast'], watch_per_profile: 2 })
16
17  // 3. Optional one-call prechecked video publish + bio CTA sync
18  let publishedAwemeId: string | undefined
19  if (videoUrl) {
20    const pre = await client.account.uploadPrecheck(accountId)
21    if (pre.data.can_publish !== false) {
22      const pub = await client.account.uploadVideo({
23        account_id: accountId,
24        video_url:  videoUrl,
25        caption:    'How 3-person SaaS teams automate inbound pipeline #saas #founders #gtm',
26        visibility: 'public',
27      })
28      publishedAwemeId = pub.data.aweme_id
29    }
30  }
31
32  // 4. Pull inbound DM threads + close foreground session cleanly
33  const inbox = await client.account.dmInbox({ account_id: accountId, count: 20 })
34  await client.account.tick(accountId)
35  await client.account.background(accountId)
36  return { accountId, publishedAwemeId, unreadThreads: (inbox.data.items ?? []).length }
37}
Warm new imports for 48–72 hours before first upload. Run warm/niche and warm/seed-accounts without uploading on Days 1–2, always check upload/precheck before upload/video, and operate strictly on accounts you own or manage under client authorization.