← back to Marketing Command Center
submissions: TikTok production App Review package (fields + scope text + demo shot-list + submit steps)
4e9c425d6a2fb2c45c1d7a634b887f567b89ed7b · 2026-07-21 16:32:17 -0700 · Steve
Files touched
A docs/submissions/tiktok-app-review.md
Diff
commit 4e9c425d6a2fb2c45c1d7a634b887f567b89ed7b
Author: Steve <steve@designerwallcoverings.com>
Date: Tue Jul 21 16:32:17 2026 -0700
submissions: TikTok production App Review package (fields + scope text + demo shot-list + submit steps)
---
docs/submissions/tiktok-app-review.md | 213 ++++++++++++++++++++++++++++++++++
1 file changed, 213 insertions(+)
diff --git a/docs/submissions/tiktok-app-review.md b/docs/submissions/tiktok-app-review.md
new file mode 100644
index 0000000..9151c4a
--- /dev/null
+++ b/docs/submissions/tiktok-app-review.md
@@ -0,0 +1,213 @@
+# TikTok App Review — Submission Package
+
+**App:** DW Marketing · **app_id** `7662772350357866516` · developers.tiktok.com
+**Owner:** @designerwallcoverings (Individual)
+**Goal:** get the **PRODUCTION** app approved for `video.publish` (Direct Post) + `video.upload`
+so `@designerwallcoverings` can post **PUBLICLY** from the Marketing Command Center.
+Today the app is unaudited → sandbox-only, private (`SELF_ONLY`) posts only.
+
+**Status going in (all verified this session):**
+- Domain `designerwallcoverings.com` **verified** in the portal (apex TXT).
+- Sandbox fully configured; a real end-to-end **SELF_ONLY post was published** to
+ `@designerwallcoverings` (publish_id `v_pub_file~v2-1.766506…`) — proves the Content Posting API works.
+- Both policy URLs return **HTTP 200** (verified `curl` this session).
+- App icon present at `~/Desktop/Images/DW-TikTok-icon.png` (1024×1024 PNG).
+- The MCC is the integration surface; OAuth + `postTikTok()` are live in `modules/channels/index.js`.
+
+---
+
+## 1. Production-app field values (paste-ready)
+
+TikTok dev portal → **Manage apps → DW Marketing → Production** tab → App details.
+Copy each cell verbatim.
+
+| Field | Value to paste |
+|---|---|
+| **App icon** | Upload `~/Desktop/Images/DW-TikTok-icon.png` (1024×1024 PNG) |
+| **App name** | `DW Marketing` |
+| **Category** | `Shopping` |
+| **Description** (≤120 chars) | `Designer Wallcoverings posts its own product and room videos to its official TikTok via the Content Posting API.` |
+| **Terms of Service URL** | `https://designerwallcoverings.com/policies/terms-of-service` |
+| **Privacy Policy URL** | `https://designerwallcoverings.com/policies/privacy-policy` |
+| **Platform** | `Web` |
+| **Web/Desktop URL** | `https://marketing.designerwallcoverings.com` |
+| **Products** | `Login Kit` + `Content Posting API` |
+| **Scopes** | `user.info.basic`, `video.publish`, `video.upload` |
+| **Redirect URI** | `https://marketing.designerwallcoverings.com/api/channels/oauth/tiktok/callback` |
+
+Description character count = **111** (≤120 ✓).
+
+**Hard rules the reviewer enforces — do not trip these:**
+- The **Web/Desktop URL domain MUST match** the domain shown on screen in the demo video →
+ both are `marketing.designerwallcoverings.com`. ✓
+- **No `localhost`** anywhere (redirect URI or web URL) — TikTok auto-rejects it.
+- The live MCC's `OAUTH_REDIRECT_BASE` is already `https://marketing.designerwallcoverings.com`,
+ so the redirect URI above is the exact one the callback code uses.
+- ToS + Privacy URLs must resolve (verified 200 this session).
+
+---
+
+## 2. "Explain how each product and scope works" — reviewer free-text
+
+Paste this verbatim into the App Review "describe how your app uses each scope/product" field.
+It is written so a reviewer can approve without follow-up: it establishes that this is a
+**single-brand, own-account** integration with no third-party or user-generated content.
+
+> Designer Wallcoverings (designerwallcoverings.com) runs a private Marketing Command Center at
+> marketing.designerwallcoverings.com that manages our OWN brand's social channels. The TikTok
+> integration lets our marketing team authenticate our OWN official account
+> (@designerwallcoverings) and publish our OWN product and room-setting videos to it. There is no
+> third-party content, no user-generated content, and no multi-account behavior — every action is
+> our brand posting to our brand's single account.
+>
+> **Login Kit — `user.info.basic`:** When our admin clicks "Connect TikTok" on the Command
+> Center's Channels page, we run the Login Kit OAuth flow to authenticate our own TikTok account.
+> We read `open_id`, `avatar_url`, and `display_name` only, and only to confirm and display in the
+> dashboard which account is connected. No other user's data is ever accessed.
+>
+> **Content Posting API — `video.publish` (Direct Post):** From the Command Center, our team
+> selects a wallcovering product or room-setting video we produced and publishes it directly to our
+> own @designerwallcoverings profile via the Content Posting API (Direct Post). The video source is
+> fetched via PULL_FROM_URL from our verified domain designerwallcoverings.com, or uploaded as
+> bytes via FILE_UPLOAD. This is how we announce new collections and room visualizations on TikTok.
+>
+> **Content Posting API — `video.upload` (draft fallback):** As a fallback, we upload a video as a
+> draft to our own account's TikTok inbox so a team member can finalize the caption and timing and
+> post it manually from the TikTok app.
+>
+> All posting is to our own single brand account. The domain designerwallcoverings.com is verified
+> in the developer portal and is the source for PULL_FROM_URL video content.
+
+---
+
+## 3. The required demo video — shot list / script
+
+TikTok App Review **mandates** a screen-recording that shows the complete end-to-end integration
+flow and **demonstrates every requested scope**. This is the part that decides the review.
+
+### Recording constraints (from the portal)
+- Format **mp4 or mov**, **≤50 MB per file**, up to 5 files.
+- **Must use the SANDBOX** app (client key `sbaw22ejwjsfwqetsy`) — production isn't approved yet,
+ so record the flow against sandbox, where posts land private (`SELF_ONLY`).
+- The **on-screen domain must match** the Web/Desktop URL → keep
+ `https://marketing.designerwallcoverings.com` visible in the address bar.
+- **All three scopes must be visibly demonstrated:** `user.info.basic` (connected account shows
+ avatar + name), `video.publish` (Direct Post → publish_id → video on account),
+ `video.upload` (draft lands in inbox).
+- Target length **~2–3 min**, narrated. Keep the mouse movements slow and deliberate.
+
+### This flow is already filmable
+A real `SELF_ONLY` post has already been fired end-to-end to @designerwallcoverings
+(publish_id `v_pub_file~v2-1.766506…`), so nothing about Scenes 3–4 is theoretical — the exact
+button-press sequence works and can be filmed live.
+
+> **One constraint to handle while filming (unaudited-app rule):**
+> `unaudited_client_can_only_post_to_private_accounts`. Before recording the post scenes, toggle
+> **@designerwallcoverings → Private ON**, record the post, then toggle **Private OFF** after.
+> A `SELF_ONLY` privacy level on the post alone is NOT enough for the unaudited sandbox — the
+> ACCOUNT itself must be Private during the post. This is a recording-time step only; production
+> approval removes it.
+
+### Scene-by-scene
+
+**Scene 1 — Context (0:00–0:15)**
+- On screen: Chrome with the address bar clearly reading `https://marketing.designerwallcoverings.com`.
+- Show the Command Center dashboard, then navigate to the **Channels** page with the TikTok card
+ in its disconnected state.
+- Narration: *"This is the Designer Wallcoverings Marketing Command Center at
+ marketing.designerwallcoverings.com. We use it to post our own brand videos to our own TikTok
+ account. Here's the Channels page."*
+
+**Scene 2 — Login Kit + `user.info.basic` (0:15–0:50)**
+- Click **Connect TikTok** on the TikTok card.
+- The TikTok OAuth consent screen appears — pause on it so the reviewer sees the app name
+ "DW Marketing" and the requested scopes (`user.info.basic`, `video.publish`, `video.upload`).
+- Click **Authorize / Continue** → redirected back to the Channels page, now showing TikTok
+ **Connected** with the account **avatar + display name** rendered.
+- Narration: *"We connect our own TikTok account through Login Kit. It asks consent for the three
+ scopes. After authorizing, the dashboard shows our connected account — that's user.info.basic,
+ which we use only to confirm which account is linked."*
+
+**Scene 3 — `video.publish` Direct Post (0:50–1:50)**
+- Select one of our product/room videos in the Command Center.
+- Choose **Post to TikTok → Direct Post** → confirm.
+- Show the success state with the returned **`publish_id`** clearly on screen.
+- Cut to the TikTok app / profile showing the newly posted video (sandbox = private/SELF_ONLY).
+- Narration: *"We select one of our own product videos and publish it directly to our account via
+ the Content Posting API. The API returns a publish_id, and the video appears on our
+ @designerwallcoverings profile. That's video.publish."*
+
+**Scene 4 — `video.upload` draft (1:50–2:20)**
+- Repeat with the **Upload as draft** option.
+- Show the video landing in the TikTok **inbox as an editable draft**.
+- Narration: *"As a fallback we can upload a video as a draft to our own inbox to finish the
+ caption and post manually. That's video.upload."*
+
+**Scene 5 — Close (2:20–2:30)**
+- Return to the Channels page showing **connected + the recent post**.
+- Narration: *"Everything posts to our own single brand account — no third-party or
+ user-generated content."*
+
+### Tools to record it
+- **Screen capture:** the **`screenrecord`** skill (`~/.claude/skills/screenrecord/`) drives the
+ live MCC and records the clickthrough; or the **`app-demo-video`** skill
+ (`~/.claude/skills/app-demo-video/`) for an auto-highlighted, narrated walkthrough.
+- **Narration voice:** the `use-voice` / `clone-voice` skill can generate the voiceover track.
+- **Keep it under 50 MB:** export mp4 h264; if a single file is too big, split into ≤5 files by
+ scene. (The 14 MB square DW promo already fits; a 106 MB reel would not.)
+
+---
+
+## 4. Exact submission steps (click-path)
+
+1. Go to **developers.tiktok.com → Manage apps → DW Marketing**.
+2. Select the **Production** view (top toggle) — NOT Sandbox. (Sandbox stays live and keeps
+ working throughout review; you're submitting the production app for audit.)
+3. **App details:** fill every field from **§1** and **upload the icon**. Save.
+4. **Products:** ensure **Login Kit** and **Content Posting API** are both added.
+5. **Scopes:** add `user.info.basic`, `video.publish`, `video.upload`.
+6. **Redirect URI:** confirm `https://marketing.designerwallcoverings.com/api/channels/oauth/tiktok/callback`
+ is registered under Login Kit.
+7. **Scope-usage explanation:** paste the **§2** free-text into the "describe how your app uses
+ each scope/product" field.
+8. **Demo video:** attach the mp4(s) recorded per **§3**.
+9. Click **Submit for review**.
+
+**What happens next:**
+- The app enters TikTok's **App Review queue** (typically a **few business days**; can be longer,
+ and reviewers sometimes reply with a change request rather than an outright decision).
+- **The sandbox keeps working the whole time** — you can keep posting `SELF_ONLY`/private test
+ posts to @designerwallcoverings while the production app is under review.
+- On **approval**, the production client key `aw1ccgi9nspzz8io` gains public `video.publish`, and
+ @designerwallcoverings can be posted to **publicly** (account no longer has to be Private).
+- If TikTok requests changes, address them and re-submit — the same package applies.
+
+---
+
+## 5. Pre-submission checklist
+
+- [x] Domain `designerwallcoverings.com` verified in portal
+- [x] Sandbox configured; real SELF_ONLY post proven end-to-end (publish_id `v_pub_file~v2-1.766506…`)
+- [x] ToS URL 200 · Privacy URL 200 (verified this session)
+- [x] App icon 1024×1024 present at `~/Desktop/Images/DW-TikTok-icon.png`
+- [x] `postTikTok()` + OAuth callback live in the MCC (`modules/channels/index.js`)
+- [x] Production field values drafted (§1) — paste-ready
+- [x] Scope-usage reviewer text drafted (§2) — paste-ready
+- [ ] Production App details filled + icon uploaded in portal *(Steve, in portal)*
+- [ ] Products/scopes/redirect confirmed in portal *(Steve, in portal)*
+- [ ] **Demo video recorded** per §3 (sandbox, domain matches, all 3 scopes shown) *(record step)*
+- [ ] **Submit for review** clicked *(Steve — gated, customer-facing/identity)*
+
+### What's already done vs what needs a human
+
+**Done / paste-ready (this package):** every field value, the ≤120-char description, both verified
+policy URLs, the exact scope-usage reviewer paragraph, the full demo shot-list, the click-path.
+The posting pipeline is proven working, so the flow in the video is real, not mocked.
+
+**Needs a human:**
+1. **Record the demo video** (§3) — a screen-recording session against the live MCC; involves
+ firing a real (private, `SELF_ONLY`) post while the account is toggled Private. This is a gated
+ publish + a filming step, so it's done live, not autonomously. The `screenrecord` /
+ `app-demo-video` skills drive the capture.
+2. **Click "Submit for review"** in the TikTok portal — Steve-only (customer-facing / identity /
+ irreversible submission). Filling the portal fields (§1/§2/§4) is also in-portal, Steve-driven.
← 33d5174 chore: v1.6.3 (session close — FB page names fix)
·
back to Marketing Command Center
·
submissions: LinkedIn dedicated-app + Community Management A eb16f00 →