Skip to content

Historical snapshot archived 2026-09-25. This records an earlier review or plan, not current implementation or live ticket state. For current work, follow root AGENTS.md, the relevant BloxClips skill, and owning repository source/tests. Preserve approved decisions as evidence; verify their present authority before acting.

External Integrations ​

Every external system involved in submission behavior.


1. Discord ​

Purpose ​

  • User authentication (Discord OAuth)
  • In-app notifications (UserNotification → Discord DM via bot? No — in-app only)
  • Campaign expiry reports (DM to user via UserChannel)
  • Admin audit log context (adminId = Discord ID)
  • Legacy: Submission approval queue (removed)

Where Invoked ​

  • src/index.ts — Bot entry point
  • src/scheduler.ts:61-150 — Campaign expiry DM reports
  • src/utils/notifications.ts — createUserNotification (in-app only)
  • src/utils/discordClient.ts — REST API client

Configuration ​

Env VarDescription
DISCORD_BOT_TOKENBot token for REST API
DISCORD_CLIENT_IDOAuth client ID
DISCORD_CLIENT_SECRETOAuth secret
GUILD_CONFIG (DB)Channels, roles

Inputs/Outputs ​

  • Input: User Discord ID, channel IDs, role IDs
  • Output: DM messages (expiry reports), audit log actor IDs

Failure Behavior ​

  • Expiry DM fails → logged, campaign still marked inactive
  • OAuth fails → user can't login

Submission Data Affected ​

  • Submission.userId = Discord ID (legacy)
  • Submission.messageId = Legacy approval message ID (unused)
  • AdminAuditLog.adminId = Discord ID
  • src/index.ts, src/scheduler.ts, src/utils/discordClient.ts, src/utils/notifications.ts

2. Apify (TikTok & Instagram Scraping) ​

Purpose ​

Scrape view counts, likes, comments, metadata for TikTok/Instagram videos

Where Invoked ​

  • src/api/routes/submissions.ts:377-427 — Submission create (first scrape)
  • src/utils/tracking/runTrackingTick.ts:237-285 — Continuous tick
  • src/utils/payouts/rescrape.ts:259-288 — Payout rescrape

Configuration ​

Env VarDescription
APIFY_TOKENApify API token
APIFY_TIKTOK_ACTOR_IDActor ID (default: clockworks/tiktok-scraper)
APIFY_INSTAGRAM_ACTOR_IDActor ID (default: apify/instagram-scraper)

Inputs ​

  • Array of video URLs
  • userKey (for cost tracking)

Outputs ​

typescript
ScrapeOk: {
  url, id, ok: true,
  views, likes, comments,
  videoTitle, previewVideoUrl, previewImageUrl,
  creatorHandle, creatorAccountId, postedAt
}
ScrapeFail: {url, id, ok: false, reason}

Failure Behavior ​

  • Actor run failed → all URLs return SCRAPE_FAILED
  • Video not found/private → VIDEO_DELETED / VIDEO_PRIVATE
  • Rate limit → run fails, retry next tick (24h backoff)
  • Cost cap → costTracker.ts records usage, no hard block

Submission Data Affected ​

  • initialViews, currentViews, initialLikes, currentLikes, currentComments
  • videoTitle, previewVideoUrl, previewImageUrl
  • creatorHandle, creatorAccountId, postedAt
  • consecutiveScrapeFailures (incremented on fail)
  • frozenViewCount (via budget clamp)

Cost Tracking ​

File: src/utils/scrapers/costTracker.ts
Records: {userKey, source: 'tiktok'|'instagram', rows: N} per batch

  • src/utils/scrapers/apify.ts, src/utils/tracking/runTrackingTick.ts, src/utils/payouts/rescrape.ts

3. YouTube Data API v3 ​

Purpose ​

Scrape YouTube video metadata (views, likes, comments, title, channel)

Where Invoked ​

  • src/api/routes/submissions.ts:350-375 — Submission create
  • src/utils/tracking/runTrackingTick.ts:201-235 — Continuous tick
  • src/utils/payouts/rescrape.ts:177-226 — Payout rescrape

Configuration ​

Env VarDescription
YOUTUBE_API_KEYYouTube Data API v3 key

Inputs ​

  • Array of video IDs (extracted from URLs)

Outputs ​

typescript
{
  views, likes, comments,
  title, creatorHandle, creatorAccountId (channelId),
  uploadDate, duration
}

Failure Behavior ​

  • Quota exceeded → batch fails, all videos SCRAPE_FAILED
  • Video not found → individual VIDEO_DELETED
  • Network error → batch fails, retry next tick

Submission Data Affected ​

  • Same as Apify + duration (YouTube provides)
  • isShort detection via isYouTubeShort(url, duration)
  • src/utils/youtube.ts, src/utils/tracking/runTrackingTick.ts, src/utils/payouts/rescrape.ts

4. Stripe (Payouts) ​

Purpose ​

Primary payout rail (bank transfers via Stripe Connect)

Where Invoked ​

  • src/utils/rails/dispatcher.ts — dispatchPayout for method=stripe
  • src/api/routes/stripe.ts — Connect onboarding, webhooks
  • src/api/routes/adminPayoutReview.ts:781 — Send payout

Configuration ​

Env VarDescription
STRIPE_SECRET_KEYStripe secret key
STRIPE_WEBHOOK_SECRETWebhook signing secret
STRIPE_PAYOUT_SURCHARGE_BPSSurcharge basis points (default 250 = 2.5%)

Flow ​

  1. User completes Stripe Connect onboarding → StripeAccount.onboardingComplete=true, payoutsEnabled=true
  2. Payout approved → AWAITING_SEND
  3. Admin clicks Send (TOTP) → dispatchPayout → Stripe Transfer
  4. Webhook transfer.paid → Payout.COMPLETED

Failure Behavior ​

  • Transfer fails → FAILED, revert paid-totals, reverse affiliate
  • Idempotency key = payoutId (prevents double-send)

Submission Data Affected ​

  • Payout.stripeTransferId
  • Payout.status → COMPLETED/FAILED
  • Submission.paidViewsTotal, paidAmountTotal (bumped on approve, reverted on terminal fail)

5. PayPal (Payouts) ​

Purpose ​

Alternative payout rail (PayPal Payouts API)

Where Invoked ​

  • src/utils/rails/dispatcher.ts — method=paypal
  • src/api/routes/paypal.ts — OAuth connect, webhooks
  • src/api/routes/adminPaypal.ts — Admin PayPal management

Configuration ​

Env VarDescription
PAYPAL_CLIENT_IDPayPal client ID
PAYPAL_CLIENT_SECRETPayPal secret
PAYPAL_PAYOUT_VOLUME_CAP_USDDaily volume cap (Phase 7b)
PAYPAL_MODEmock or live

Failure Behavior ​

  • Circuit breaker: 3 failures → paypalCircuitOpenedAt, all PayPal sends fail-fast until admin clears
  • Volume cap exceeded → reject new PayPal payouts
  • Mock mode → no real money moves

6. NowPayments (USDT Payouts) ​

Purpose ​

Crypto payout rail (USDT TRC-20)

Where Invoked ​

  • src/utils/rails/dispatcher.ts — method=usdt
  • src/utils/nowpayments/client.ts — NowPayments API
  • src/api/routes/usdt.ts — Wallet management

Configuration ​

Env VarDescription
NOWPAYMENTS_API_KEYNowPayments API key
USDT_NETWORKTRC20 (hardcoded)

Failure Behavior ​

  • Network fee recorded in Payout.usdtNetworkFee
  • On-chain tx hash in Payout.onChainTxHash

7. Resend (Email) ​

Purpose ​

Transactional emails (campaign launch, payout notifications, tax forms)

Where Invoked ​

  • src/utils/email.ts — sendCampaignLaunchEmail, sendCampaignUpdateEmail, sendAdminWarningEmail
  • src/utils/notifications.ts — notifyPayoutSent, notifyPayoutRejected (if email opted in)

Configuration ​

Env VarDescription
RESEND_API_KEYResend API key
EMAIL_FROMFrom address

8. Tax1099 (Tax Compliance) ​

Purpose ​

W-9/W-8BEN verification, TIN matching, 1099-NEC filing

Where Invoked ​

  • src/utils/tax1099/client.ts — Tax1099 API
  • src/utils/tax/taxForm.ts — Form lifecycle
  • src/api/routes/taxForms.ts — User tax form submission
  • src/api/routes/adminTaxForms.ts — Admin review

Configuration ​

Env VarDescription
TAX1099_API_KEYTax1099 API key
TAX1099_API_SECRETTax1099 secret

9. Roblox (Game Data) ​

Purpose ​

Game thumbnail, title, player count for campaigns

Where Invoked ​

  • src/utils/roblox.ts — getGameInfo, getGameThumbnail
  • src/scheduler.ts:62 — Campaign expiry thumbnail
  • src/api/routes/admin.ts:48 — Campaign thumbnail resolution

Configuration ​

None (public Roblox APIs)


10. Turnstile (CAPTCHA) ​

Purpose ​

Contact form spam protection

Where Invoked ​

  • src/api/routes/contact.ts — Contact form validation

Configuration ​

Env VarDescription
TURNSTILE_SECRET_KEYCloudflare Turnstile secret

11. S3/R2 (File Storage) ​

Purpose ​

Tax form PDFs, video previews (if stored)

Where Invoked ​

  • src/utils/storage/r2.ts — Cloudflare R2
  • src/utils/storage/local.ts — Local dev
  • src/utils/storage/tamperDetect.ts — PDF integrity

Configuration ​

Env VarDescription
R2_ACCOUNT_IDCloudflare account ID
R2_ACCESS_KEY_IDR2 access key
R2_SECRET_ACCESS_KEYR2 secret
R2_BUCKETBucket name

Summary Table ​

IntegrationAuthUsed By SubmissionsCritical Path
DiscordBot tokenNotifications, expiry reportsNo (legacy approval removed)
ApifyAPI tokenTikTok/IG scrapingYes — metrics
YouTube Data APIAPI keyYouTube scrapingYes — metrics
StripeSecret keyPayout dispatchYes — payouts
PayPalOAuthPayout dispatchYes — payouts
NowPaymentsAPI keyUSDT payoutsYes — payouts
ResendAPI keyEmailsNo
Tax1099API keyTax formsNo (payout gate)
RobloxNoneCampaign dataNo
TurnstileSecretContact formNo
R2CredentialsPDF storageNo