{"_id":"@bernierllc/social-media-tiktok","_rev":"4-733e9b1cf8569908de74f667b90a17a9","name":"@bernierllc/social-media-tiktok","dist-tags":{"latest":"1.2.1"},"versions":{"0.0.0":{"name":"@bernierllc/social-media-tiktok","version":"0.0.0","keywords":["oidc","trusted-publishing","setup"],"_id":"@bernierllc/social-media-tiktok@0.0.0","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"dist":{"shasum":"37db683ee1bbafb519e23f63d79e8cf8ea39e55e","tarball":"https://registry.npmjs.org/@bernierllc/social-media-tiktok/-/social-media-tiktok-0.0.0.tgz","fileCount":2,"integrity":"sha512-kA646ZsKhLv0FXjwKJ0WJXAdhnGosdh9P1rxUreL4Mb8gyzE6w8j4Kut9jB8apC/I23kVdFgWKTQfL3bLurG/A==","signatures":[{"sig":"MEQCIA4sI97nYAQTqJcRhLQC9/eqHFvNEXMNEFc9ph3hz0ruAiBuydNla96DhNR/7Y/4saPTWvTII0RRAxJQNziCsuPk0Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":2087},"_npmUser":{"name":"mkbernier","email":"mkbernier@gmail.com"},"_npmVersion":"11.16.0","description":"OIDC trusted publishing setup package for @bernierllc/social-media-tiktok","directories":{},"_nodeVersion":"26.3.1","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/social-media-tiktok_0.0.0_1785868611523_0.08889008989332314","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@bernierllc/social-media-tiktok","version":"1.1.0","keywords":["tiktok","social-media","api","oauth2","content-posting","video","direct-post","bernierllc"],"author":{"name":"Bernier LLC"},"license":"SEE LICENSE IN LICENSE","_id":"@bernierllc/social-media-tiktok@1.1.0","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"homepage":"https://github.com/bernierllc/tools#readme","bugs":{"url":"https://github.com/bernierllc/tools/issues"},"dist":{"shasum":"18cce240e0fe376afa2bdb2a203ba3662512d357","tarball":"https://registry.npmjs.org/@bernierllc/social-media-tiktok/-/social-media-tiktok-1.1.0.tgz","fileCount":19,"integrity":"sha512-ZICK1h+e1vacwSV3xdGSCfksBgW1PTZtUWrRPEBFSbwShiK5ll4pTsIzI+7s5pCHIhEWLEOXtl/5lgpEfHd3Wg==","signatures":[{"sig":"MEUCIHaqMCbGJNibo4Vi5tWjmbf4L3p0am4SC3r19CRlogbNAiEA3f8Rlt5bOfV6yxn6XcXlL3zF3yhwrkCtMOcfgqUERtc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":39147},"main":"dist/index.js","type":"module","_from":"file:bernierllc-social-media-tiktok-1.1.0.tgz","types":"dist/index.d.ts","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"lint":"eslint src --ext .ts","test":"NODE_OPTIONS='--experimental-vm-modules' jest --watch","build":"tsc","clean":"rimraf dist","lint:fix":"eslint src --ext .ts --fix","prebuild":"npm run clean","test:run":"NODE_OPTIONS='--experimental-vm-modules' jest --passWithNoTests","test:coverage":"NODE_OPTIONS='--experimental-vm-modules' jest --coverage --passWithNoTests"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:41636842-9e4e-488d-a68e-8d1154daf4f8"}},"_resolved":"/home/runner/work/tools/tools/packages/service/social-media-tiktok/bernierllc-social-media-tiktok-1.1.0.tgz","_integrity":"sha512-ZICK1h+e1vacwSV3xdGSCfksBgW1PTZtUWrRPEBFSbwShiK5ll4pTsIzI+7s5pCHIhEWLEOXtl/5lgpEfHd3Wg==","bernierllc":{"integration":{"logger":"integrated","neverhub":"required","docsIntegration":"ready"}},"repository":{"url":"git+https://github.com/bernierllc/tools.git","type":"git","directory":"packages/service/social-media-tiktok"},"_npmVersion":"12.0.2","description":"TikTok Content Posting API integration service with OAuth 2.0 authentication, direct-post video publishing (PULL_FROM_URL), and publish status polling","directories":{},"_nodeVersion":"24.18.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^8.57.0","rimraf":"^5.0.7","ts-jest":"^29.1.4","typescript":"^5.4.5","@types/jest":"^29.5.12","@types/node":"^20.14.0","@typescript-eslint/parser":"^7.0.0","@typescript-eslint/eslint-plugin":"^7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/social-media-tiktok_1.1.0_1785868851465_0.14618771621805715","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"@bernierllc/social-media-tiktok","version":"1.2.0","keywords":["tiktok","social-media","api","oauth2","content-posting","video","direct-post","bernierllc"],"author":{"name":"Bernier LLC"},"license":"SEE LICENSE IN LICENSE","_id":"@bernierllc/social-media-tiktok@1.2.0","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"homepage":"https://github.com/bernierllc/tools#readme","bugs":{"url":"https://github.com/bernierllc/tools/issues"},"dist":{"shasum":"d680975e0c69d067378b50ea6c30f48897363bbe","tarball":"https://registry.npmjs.org/@bernierllc/social-media-tiktok/-/social-media-tiktok-1.2.0.tgz","fileCount":19,"integrity":"sha512-g/ThjsXKXPPjzQfp6BLuIQ2Y+xqKVkdH9ToOtesKZqbEBcGVNg8GpBFExUonxuzKqYb1++AqavCUZ7YjY84Miw==","signatures":[{"sig":"MEUCIQCAKBTSzb8oNyUkjgR3sm9qGD8JKCA4dy4he1TwqNJHgAIgaS6lFUaaT/LawFTUll/+8kmCEmry+pS/i/tFkXob2Xg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":42043},"main":"dist/index.js","type":"module","_from":"file:bernierllc-social-media-tiktok-1.2.0.tgz","types":"dist/index.d.ts","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"lint":"eslint src --ext .ts","test":"NODE_OPTIONS='--experimental-vm-modules' jest --watch","build":"tsc","clean":"rimraf dist","lint:fix":"eslint src --ext .ts --fix","prebuild":"npm run clean","test:run":"NODE_OPTIONS='--experimental-vm-modules' jest --passWithNoTests","test:coverage":"NODE_OPTIONS='--experimental-vm-modules' jest --coverage --passWithNoTests"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:41636842-9e4e-488d-a68e-8d1154daf4f8"}},"_resolved":"/home/runner/work/tools/tools/packages/service/social-media-tiktok/bernierllc-social-media-tiktok-1.2.0.tgz","_integrity":"sha512-g/ThjsXKXPPjzQfp6BLuIQ2Y+xqKVkdH9ToOtesKZqbEBcGVNg8GpBFExUonxuzKqYb1++AqavCUZ7YjY84Miw==","bernierllc":{"integration":{"logger":"integrated","neverhub":"required","docsIntegration":"ready"}},"repository":{"url":"git+https://github.com/bernierllc/tools.git","type":"git","directory":"packages/service/social-media-tiktok"},"_npmVersion":"12.0.2","description":"TikTok Content Posting API integration service with OAuth 2.0 authentication, direct-post video publishing (PULL_FROM_URL), and publish status polling","directories":{},"_nodeVersion":"24.18.0","dependencies":{"@bernierllc/neverhub-adapter":"0.4.1"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^8.57.0","rimraf":"^5.0.7","ts-jest":"^29.1.4","typescript":"^5.4.5","@types/jest":"^29.5.12","@types/node":"^20.14.0","@typescript-eslint/parser":"^7.0.0","@typescript-eslint/eslint-plugin":"^7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/social-media-tiktok_1.2.0_1785876753291_0.9009294439306557","host":"s3://npm-registry-packages-npm-production"}},"1.2.1":{"_id":"@bernierllc/social-media-tiktok@1.2.1","bugs":{"url":"https://github.com/bernierllc/tools/issues"},"dist":{"shasum":"64ba52827673dfc3e635a7a18c0abf36e0c8f25b","tarball":"https://registry.npmjs.org/@bernierllc/social-media-tiktok/-/social-media-tiktok-1.2.1.tgz","fileCount":19,"integrity":"sha512-7THOKkudunkSfq482JGX0cppaa3ER7+DfDc0Ho2guet46c3P/5P4c9Vl8fTkMpop5+HFBp9SeoD7KVW4rUVv+w==","signatures":[{"sig":"MEQCIFFYP2XWMyh/+HaOaiEpAbKMq3AaNtXIX4SRNLNIFglYAiABn2tZtvbMxpkP9Qx7VclorQKoFgM1HYW5CLnzC9XmTA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQC1a0X0yxotU7QJoo/dm+hkxEr011oeaACOn4xt0vOyFwIhAKe7GrjdmPzcV98S5H6rTHOMDNlKA8ZiWiqsLPbm7EE4"}],"unpackedSize":42044},"main":"dist/index.js","name":"@bernierllc/social-media-tiktok","type":"module","_from":"file:bernierllc-social-media-tiktok-1.2.1.tgz","types":"dist/index.d.ts","author":{"name":"Bernier LLC"},"engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"license":"SEE LICENSE IN LICENSE","scripts":{"lint":"eslint src --ext .ts","test":"NODE_OPTIONS='--experimental-vm-modules' jest --watch","build":"tsc","clean":"rimraf dist","lint:fix":"eslint src --ext .ts --fix","prebuild":"npm run clean","test:run":"NODE_OPTIONS='--experimental-vm-modules' jest --passWithNoTests","test:coverage":"NODE_OPTIONS='--experimental-vm-modules' jest --coverage --passWithNoTests"},"version":"1.2.1","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"41636842-9e4e-488d-a68e-8d1154daf4f8"}},"homepage":"https://github.com/bernierllc/tools#readme","keywords":["tiktok","social-media","api","oauth2","content-posting","video","direct-post","bernierllc"],"_resolved":"/home/runner/work/tools/tools/packages/service/social-media-tiktok/bernierllc-social-media-tiktok-1.2.1.tgz","_integrity":"sha512-7THOKkudunkSfq482JGX0cppaa3ER7+DfDc0Ho2guet46c3P/5P4c9Vl8fTkMpop5+HFBp9SeoD7KVW4rUVv+w==","bernierllc":{"integration":{"logger":"integrated","neverhub":"required","docsIntegration":"ready"}},"repository":{"url":"git+https://github.com/bernierllc/tools.git","type":"git","directory":"packages/service/social-media-tiktok"},"_npmVersion":"12.2.0","description":"TikTok Content Posting API integration service with OAuth 2.0 authentication, direct-post video publishing (PULL_FROM_URL), and publish status polling","directories":{},"maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"_nodeVersion":"24.21.0","dependencies":{"@bernierllc/neverhub-adapter":"^0.4.1"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^8.57.0","rimraf":"^5.0.7","ts-jest":"^29.1.4","typescript":"^5.4.5","@types/jest":"^29.5.12","@types/node":"^20.14.0","@typescript-eslint/parser":"^7.0.0","@typescript-eslint/eslint-plugin":"^7.0.0"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/social-media-tiktok_1.2.1_1790884494271_0.9056507192187997"}}},"time":{"created":"2026-08-04T18:36:51.337Z","modified":"2026-10-01T19:54:54.646Z","0.0.0":"2026-08-04T18:36:51.689Z","1.1.0":"2026-08-04T18:40:51.638Z","1.2.0":"2026-08-04T20:52:33.437Z","1.2.1":"2026-10-01T19:54:54.363Z"},"bugs":{"url":"https://github.com/bernierllc/tools/issues"},"author":{"name":"Bernier LLC"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/bernierllc/tools#readme","keywords":["tiktok","social-media","api","oauth2","content-posting","video","direct-post","bernierllc"],"repository":{"url":"git+https://github.com/bernierllc/tools.git","type":"git","directory":"packages/service/social-media-tiktok"},"description":"TikTok Content Posting API integration service with OAuth 2.0 authentication, direct-post video publishing (PULL_FROM_URL), and publish status polling","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"readme":"# @bernierllc/social-media-tiktok\n\nTikTok Content Posting API integration service with OAuth 2.0 authentication, direct-post video publishing (`PULL_FROM_URL`), and publish status polling.\n\n## ⚠️ Unaudited apps: private/draft content only\n\n**Until your TikTok developer app passes TikTok's audit review, direct-post content can only be published as private/draft** — you must use `privacyLevel: 'SELF_ONLY'`. Public privacy levels (`PUBLIC_TO_EVERYONE`, `MUTUAL_FOLLOW_FRIENDS`, `FOLLOWER_OF_CREATOR`) are rejected by TikTok for unaudited apps. See TikTok's [Content Posting API guide](https://developers.tiktok.com/doc/content-posting-api-get-started) for the audit process.\n\n## Features\n\n- **OAuth 2.0 Authentication**: Authorization URL builder, code→token exchange, refresh token flow\n- **Direct Post Publishing**: `PULL_FROM_URL` video init against the Content Posting API\n- **Publish Status Polling**: Poll the documented fetch-status endpoint for `PROCESSING_DOWNLOAD` → `PUBLISH_COMPLETE`/`FAILED`\n- **Single-account**: one `TiktokService` instance holds one account's credentials — create multiple instances for multiple accounts\n- **NeverHub**: Optional service-discovery registration with graceful degradation\n- **TypeScript Support**: Full type definitions included\n\n## Installation\n\n```bash\nnpm install @bernierllc/social-media-tiktok\n```\n\n## Quick Start\n\n```typescript\nimport { TiktokService } from '@bernierllc/social-media-tiktok';\n\nconst tiktok = new TiktokService({\n  clientKey: process.env.TIKTOK_CLIENT_KEY!,\n  clientSecret: process.env.TIKTOK_CLIENT_SECRET!,\n  redirectUri: 'https://my-app.com/callback',\n});\n```\n\n### Authentication Flow\n\n```typescript\n// 1. Build the authorization URL and redirect the user to it\nconst state = crypto.randomUUID();\nconst authUrl = tiktok.getAuthorizationUrl(['user.info.basic', 'video.publish'], state);\n\n// 2. After TikTok redirects back with ?code=...&state=...,\n//    verify `state` matches what you generated, then exchange the code\nconst credentials = await tiktok.authenticate(code);\nconsole.log('Authenticated:', credentials.openId);\n\n// 3. Refresh when the access token expires (documented as 24h validity;\n//    refresh token is valid 365d)\nconst refreshed = await tiktok.refreshAccessToken();\n```\n\n### Publishing a Video (Direct Post, PULL_FROM_URL)\n\n```typescript\nconst post = await tiktok.post({\n  postInfo: {\n    privacyLevel: 'SELF_ONLY', // required until your app passes audit\n    title: 'Hello TikTok!',\n    disableComment: false,\n  },\n  sourceInfo: {\n    source: 'PULL_FROM_URL',\n    videoUrl: 'https://cdn.example.com/my-video.mp4', // must be publicly reachable\n  },\n});\n\nif (post.success) {\n  console.log('Publish ID:', post.publishId);\n}\n```\n\n### Polling Publish Status\n\n```typescript\nconst status = await tiktok.getPublishStatus(post.publishId!);\n\nswitch (status.status) {\n  case 'PUBLISH_COMPLETE':\n    console.log('Live:', status.publiclyAvailablePostId);\n    break;\n  case 'FAILED':\n    console.error('Failed:', status.failReason);\n    break;\n  default:\n    // PROCESSING_DOWNLOAD, PROCESSING_UPLOAD, SEND_TO_USER_INBOX — poll again later\n    break;\n}\n```\n\n### NeverHub Service Discovery\n\n`initialize()` registers the service with NeverHub. It is entirely optional —\nevery method below works without calling it — and it is safe to call when\nNeverHub is not running: registration silently no-ops in degraded mode.\n\n```typescript\nawait tiktok.initialize();\n```\n\n## API Reference\n\n### `TiktokService`\n\n| Method | Description |\n|---|---|\n| `getAuthorizationUrl(scopes, state)` | Builds the `https://www.tiktok.com/v2/auth/authorize/` URL |\n| `authenticate(code)` | Exchanges an authorization code for credentials (stores them on the instance) |\n| `refreshAccessToken(refreshToken?)` | Refreshes the access token |\n| `post(request)` | Initiates a direct-post video publish (`PULL_FROM_URL`) |\n| `getPublishStatus(publishId)` | Polls publish status |\n| `isAuthenticated()` | Whether credentials are stored |\n| `getCredentials()` | Returns stored credentials, or `null` |\n\n### Documented scopes\n\n`user.info.basic`, `video.list`, `video.upload`, `video.publish` — request only the scopes your feature needs.\n\n### Documented publish statuses\n\n`PROCESSING_UPLOAD`, `PROCESSING_DOWNLOAD`, `SEND_TO_USER_INBOX`, `PUBLISH_COMPLETE`, `FAILED`\n\n## Error Handling\n\nAll unexpected/network failures throw `SocialMediaTiktokError` (extends `Error`, uses `Error.cause`). Expected API-level failures (not authenticated, TikTok error envelope) return a `{ success: false, error, errorCode? }` result instead of throwing, matching sibling `@bernierllc/social-media-*` packages.\n\n```typescript\nimport { SocialMediaTiktokError } from '@bernierllc/social-media-tiktok';\n\ntry {\n  await tiktok.authenticate(code);\n} catch (error) {\n  if (error instanceof SocialMediaTiktokError) {\n    console.error(error.code, error.message, error.cause);\n  }\n}\n```\n\n## References\n\n- [TikTok Content Posting API — Get Started](https://developers.tiktok.com/doc/content-posting-api-get-started)\n- [Direct Post reference](https://developers.tiktok.com/doc/content-posting-api-reference-direct-post)\n- [Get Post Status reference](https://developers.tiktok.com/doc/content-posting-api-reference-get-video-status)\n- [OAuth / User Access Token Management](https://developers.tiktok.com/doc/oauth-user-access-token-management)\n\n## License\n\nSEE LICENSE IN LICENSE\n","readmeFilename":"README.md"}