upload-post 2.10.0__tar.gz → 2.13.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: upload-post
3
- Version: 2.10.0
3
+ Version: 2.13.0
4
4
  Summary: Cross-platform social media upload for TikTok, Instagram, YouTube, LinkedIn, Facebook, Pinterest, Threads, Reddit, Bluesky, Discord, Telegram, and X (Twitter)
5
5
  Home-page: https://www.upload-post.com/
6
6
  Author: Upload-Post
@@ -76,6 +76,8 @@ print(response)
76
76
  - ✅ **Posting Queue** - Add posts to your configured queue
77
77
  - ✅ **First Comments** - Auto-post first comment after publishing
78
78
  - ✅ **Analytics** - Get engagement metrics
79
+ - ✅ **Audience** - Who follows a profile, per platform
80
+ - ✅ **Suggestions** - Hashtags and searches to post about, per platform
79
81
  - ✅ **Full Type Hints**
80
82
 
81
83
  ## API Reference
@@ -322,17 +324,183 @@ found = client.search_tiktok_music("my-profile", q="bad bunny", country_code="ES
322
324
  locations = client.get_tiktok_locations("my-profile", "Madrid")
323
325
  ```
324
326
 
327
+ ### Comments
328
+
329
+ The same methods cover every platform that has comments — Instagram, Facebook,
330
+ YouTube, LinkedIn and TikTok. There is no per-network method: the endpoint
331
+ answers one question and `platform` says who to ask.
332
+
333
+ ```python
334
+ # Read the comments on a post. TikTok has no post-URL lookup: pass the video id.
335
+ comments = client.get_post_comments(
336
+ user="my-profile",
337
+ platform="tiktok",
338
+ post_id="7412345678901234567",
339
+ limit=20,
340
+ )
341
+
342
+ # Read the replies hanging from one of them — same question, one more parameter
343
+ replies = client.get_post_comments(
344
+ user="my-profile",
345
+ platform="tiktok",
346
+ post_id="7412345678901234567",
347
+ comment_id="7412345678909999999",
348
+ )
349
+
350
+ # Comment on the post, or reply to a comment
351
+ client.create_comment(
352
+ user="my-profile",
353
+ platform="tiktok",
354
+ post_id="7412345678901234567",
355
+ message="Thanks for watching!",
356
+ )
357
+ client.create_comment(
358
+ user="my-profile",
359
+ platform="tiktok",
360
+ comment_id="7412345678909999999",
361
+ message="Glad you liked it",
362
+ )
363
+
364
+ # Delete one
365
+ client.delete_comment(
366
+ user="my-profile", platform="tiktok", comment_id="7412345678909999999"
367
+ )
368
+ ```
369
+
370
+ You can also have the first comment posted for you right after publishing, with
371
+ `first_comment` for every platform or `tiktok_first_comment` for TikTok alone.
372
+
373
+ On TikTok all of this needs the `comments` capability, which the account grants
374
+ when it connects — see
375
+ [What a TikTok connection can do](#what-a-tiktok-connection-can-do-capabilities).
376
+
377
+ #### Moderating a comment: hide, like, pin
378
+
379
+ `comment_action()` does the three and undoes them, on any platform that
380
+ supports it. Each action carries its own inverse, and `post_id` is only sent
381
+ when the platform needs it:
382
+
383
+ ```python
384
+ client.comment_action(
385
+ user="my-profile", platform="tiktok", action="hide",
386
+ comment_id="7412345678909999999", post_id="7412345678901234567",
387
+ )
388
+ client.comment_action(
389
+ user="my-profile", platform="tiktok", action="like",
390
+ comment_id="7412345678909999999",
391
+ )
392
+ client.comment_action(
393
+ user="my-profile", platform="tiktok", action="unpin",
394
+ comment_id="7412345678909999999", post_id="7412345678901234567",
395
+ )
396
+ ```
397
+
398
+ | `action` | Undo | `post_id` |
399
+ | --- | --- | --- |
400
+ | `hide` | `unhide` | required |
401
+ | `like` | `unlike` | not sent |
402
+ | `pin` | `unpin` | required |
403
+
404
+ ### Audience
405
+
406
+ Where the analytics methods answer *how did my posts do*, `get_audience()`
407
+ answers *who is following me*. One endpoint, one `platform` parameter, like
408
+ every other question in the API.
409
+
410
+ ```python
411
+ audience = client.get_audience(
412
+ user="my-profile",
413
+ platform="tiktok",
414
+ start_date="2026-07-01",
415
+ end_date="2026-07-30",
416
+ )
417
+
418
+ print(audience["range"]) # the window actually used
419
+ print(audience["audience"]["countries"]) # and "cities", "ages", "genders"
420
+ print(audience["activity_by_hour"]) # [{"hour": "14", "followers_online": 1494}, ...]
421
+ print(audience["followers_daily"]) # [{"date", "total", "new", "lost"}, ...]
422
+ print(audience["profile_actions"]) # bio link, address, email, phone, leads
423
+ print(audience["bio_description"])
424
+ ```
425
+
426
+ The window is clamped on the server: at most 60 days, and `end_date` always
427
+ before today. A wider window is trimmed to what the platform accepts instead of
428
+ failing.
429
+
430
+ Ask for a `benchmark_category` and the same call also returns how the account
431
+ compares with the average of that category. The accepted categories come back in
432
+ `benchmark_categories` on every response, so a picker needs no second call:
433
+
434
+ ```python
435
+ categories = client.get_audience(
436
+ user="my-profile", platform="tiktok"
437
+ )["benchmark_categories"]
438
+
439
+ benchmark = client.get_audience(
440
+ user="my-profile", platform="tiktok",
441
+ benchmark_category="SOFTWARE_AND_APPS",
442
+ )["benchmark"]
443
+ print(benchmark["average_engagement_rate"], benchmark["average_video_views"])
444
+ ```
445
+
446
+ ### Suggestions
447
+
448
+ `get_suggestions()` answers *what is worth posting about*: the hashtags or the
449
+ searches a platform suggests around a keyword. One endpoint for both, told apart
450
+ by `type`.
451
+
452
+ ```python
453
+ hashtags = client.get_suggestions(
454
+ user="my-profile", platform="tiktok", type="hashtags",
455
+ q="pilates", country_code="ES", language="es",
456
+ )["hashtags"]
457
+ print(hashtags) # [{"name": ..., "view_count": ...}, ...]
458
+
459
+ keywords = client.get_suggestions(
460
+ user="my-profile", platform="tiktok", type="keywords", q="pilates",
461
+ )["keywords"]
462
+ ```
463
+
464
+ Per-post numbers stay in `get_post_analytics()`. On TikTok that response carries
465
+ more than the usual counters: `retention` (the curve, second by second),
466
+ `impression_sources` (For You, search, profile...), `audience_types` (followers
467
+ vs non-followers), `new_followers`, `reach` and the watch times.
468
+
469
+ Asking a platform a question it cannot answer fails with
470
+ `platform_not_supported` and the list of the ones that can.
471
+
472
+ ## What a TikTok connection can do (`capabilities`)
473
+
474
+ Not every TikTok connection can do the same things. `client.list_users()`
475
+ (`GET /api/uploadposts/users`) returns a `capabilities` array on each profile's
476
+ TikTok account; check it before offering a feature.
477
+
478
+ | Capability | What it unlocks |
479
+ | --- | --- |
480
+ | `music` | `tiktok_music_id` and the volume/trim fields, plus `get_tiktok_trending_music()` and `search_tiktok_music()` |
481
+ | `location` | `tiktok_location_id` / `tiktok_location_name`, plus `get_tiktok_locations()` |
482
+ | `cover_image` | `tiktok_cover_image_url` |
483
+ | `cover_timestamp` | `cover_timestamp` |
484
+ | `draft` | `tiktok_upload_to_draft` or `post_mode="MEDIA_UPLOAD"` (same draft) |
485
+ | `video_privacy` | `privacy_level` on video |
486
+ | `photo_privacy` | `privacy_level` on photo posts |
487
+ | `profile_analytics` | `get_audience()` and `get_suggestions(type="hashtags")` with `platform="tiktok"` |
488
+ | `comments` | Comments on TikTok: `get_post_comments()` (top-level and replies), `create_comment()`, `delete_comment()`, `comment_action()` and `tiktok_first_comment` |
489
+ | `trend_search` | `get_suggestions(type="keywords")` with `platform="tiktok"` |
490
+
491
+ > **`comments` and `trend_search` need the account to be reconnected.** TikTok
492
+ > grants them at connect time, so an account linked before they existed keeps
493
+ > working for everything else but will not list them — reconnect it from Manage
494
+ > Users to enable them.
495
+
496
+ If a connection lacks a capability the upload field is simply ignored: the post
497
+ still publishes and the response carries a per-field `warnings` string. The
498
+ methods above answer with an error asking for a reconnection.
499
+
325
500
  ## TikTok music, location, cover and drafts
326
501
 
327
- > **Capabilities.** These options are available on connections that declare the
328
- > matching capability (`music`, `location`, `cover_image`, `draft`) — see the
329
- > `capabilities` array on the TikTok account returned by
330
- > `GET /api/uploadposts/users` (`client.list_users()`). Other values that can
331
- > appear there: `cover_timestamp`, `photo_privacy`, `video_privacy`,
332
- > `inbox_fallback` and `profile_analytics`. If your connection does
333
- > not have the capability, the field is ignored, the post still publishes, and
334
- > the response includes a per-field `warnings` string — reconnect the TikTok
335
- > account to enable it.
502
+ > Needs the `music`, `location`, `cover_image` or `draft` capability — see
503
+ > [What a TikTok connection can do](#what-a-tiktok-connection-can-do-capabilities).
336
504
 
337
505
  ```python
338
506
  # 1. Pick a track and a place
@@ -360,7 +528,7 @@ client.upload_video(
360
528
 
361
529
  tiktok_cover_image_url="https://example.com/cover.jpg",
362
530
  tiktok_is_ai_generated=False,
363
- tiktok_upload_to_draft=False, # True sends it to drafts and ignores the rest
531
+ tiktok_upload_to_draft=False, # same draft as post_mode="MEDIA_UPLOAD"
364
532
  )
365
533
  ```
366
534
 
@@ -376,10 +544,13 @@ client.upload_video(
376
544
  | `tiktok_location_id` | str | `location` | Video + photos. `location_id` from `get_tiktok_locations()` |
377
545
  | `tiktok_location_name` | str | `location` | Required whenever `tiktok_location_id` is set |
378
546
  | `tiktok_cover_image_url` | str | `cover_image` | Video only. Custom cover image URL |
379
- | `tiktok_is_ai_generated` | bool | — | Video + photos. AI-generated content disclosure |
380
- | `tiktok_upload_to_draft` | bool | `draft` | Video only. Publish to drafts; TikTok ignores the rest of the post settings |
547
+ | `tiktok_is_ai_generated` | bool | — | Video + photos. AI-generated content disclosure (aliases: `is_ai_generated`) |
548
+ | `tiktok_upload_to_draft` | bool | `draft` | Video + photos. Same draft as `post_mode="MEDIA_UPLOAD"` (aliases: `upload_to_draft`, `is_draft`). TikTok ignores the rest of the post settings |
549
+ | `tiktok_is_ads_only` | bool | — | Video. Only show in ads (alias: `is_ads_only`) |
550
+ | `tiktok_tto_invite_link` | str | — | Video. TikTok One invite link; needs branded content (alias: `tto_invite_link`) |
381
551
  | `photo_cover_index` | int | — | Cover photo index for photo posts (0-based) |
382
552
  | `privacy_level` | str | `photo_privacy` / `video_privacy` | Accepted on video and photo posts alike; which values the account may use is decided by TikTok, see the note below |
553
+ | `post_mode` | str | `draft` | `DIRECT_POST` or `MEDIA_UPLOAD`. `MEDIA_UPLOAD` is the same draft as `tiktok_upload_to_draft=True` |
383
554
 
384
555
  ## Platform-Specific Options
385
556
 
@@ -389,9 +560,11 @@ client.upload_video(
389
560
  - `disable_stitch` - Disable stitch
390
561
  - `cover_timestamp` - Timestamp in ms for cover
391
562
  - `is_aigc` - AI-generated content flag
392
- - `post_mode` - DIRECT_POST or MEDIA_UPLOAD
563
+ - `post_mode` - DIRECT_POST or MEDIA_UPLOAD. `MEDIA_UPLOAD` is the same draft as `tiktok_upload_to_draft=True`
393
564
  - `brand_content_toggle` - Branded content toggle
394
565
  - `brand_organic_toggle` - Brand organic toggle
566
+ - `tiktok_is_ads_only` - Only show the video in ads (alias: `is_ads_only`)
567
+ - `tiktok_tto_invite_link` - TikTok One invite link; needs branded content (alias: `tto_invite_link`)
395
568
 
396
569
  > **TikTok particularity:** `privacy_level` works on video and photo posts
397
570
  > alike, but **TikTok decides per account which values are available**. A
@@ -410,17 +583,19 @@ for the music, location, cover and draft options.
410
583
 
411
584
  ### TikTok (Photos)
412
585
  - `privacy_level` - PUBLIC_TO_EVERYONE, MUTUAL_FOLLOW_FRIENDS, FOLLOWER_OF_CREATOR, SELF_ONLY
413
- - `post_mode` - DIRECT_POST or MEDIA_UPLOAD
586
+ - `post_mode` - DIRECT_POST or MEDIA_UPLOAD. `MEDIA_UPLOAD` is the same draft as `tiktok_upload_to_draft=True`
414
587
  - `auto_add_music` - Auto add music
415
588
  - `photo_cover_index` - Index of photo for cover (0-based)
416
589
  - `disable_comment` - Disable comments
417
590
  - `tiktok_music_id` - Commercial Music Library track id
418
591
  - `tiktok_location_id` / `tiktok_location_name` - Location tag, both required together
419
592
  - `tiktok_is_ai_generated` - AI-generated content disclosure
593
+ - `tiktok_upload_to_draft` - Same draft as `post_mode="MEDIA_UPLOAD"` (aliases: `upload_to_draft`, `is_draft`)
420
594
 
421
595
  > TikTok's photo contract takes the music track id alone: `tiktok_music_volume`,
422
- > `tiktok_music_start`, `tiktok_music_end`, `tiktok_original_sound_volume`,
423
- > `tiktok_cover_image_url` and `tiktok_upload_to_draft` are video-only.
596
+ > `tiktok_music_start`, `tiktok_music_end`, `tiktok_original_sound_volume` and
597
+ > `tiktok_cover_image_url` are video-only. `post_mode="MEDIA_UPLOAD"` and
598
+ > `tiktok_upload_to_draft=True` are aliases of the same draft.
424
599
 
425
600
  ### Instagram
426
601
  - `media_type` - REELS, STORIES, IMAGE
@@ -431,6 +606,7 @@ for the music, location, cover and draft options.
431
606
  - `user_tags` - Comma-separated user tags
432
607
  - `location_id` - Location ID
433
608
  - `thumb_offset` - Thumbnail offset
609
+ - `instagram_alt_text` - Alt text (string, or JSON list / one per carousel item)
434
610
 
435
611
  ### YouTube
436
612
  - `tags` - List or comma-separated tags
@@ -448,10 +624,19 @@ for the music, location, cover and draft options.
448
624
  - `hasPaidProductPlacement` - Paid placement flag
449
625
  - `recordingDate` - Recording date (ISO 8601)
450
626
  - `youtube_playlist_id` - Playlist ID (single string, list, or comma-separated) to add the uploaded video to after publishing
627
+ - `youtube_notify_subscribers` - Notify subscribers (default `true`; send `false` to skip)
628
+ - `youtube_publish_at` - RFC3339 time; uploads as private and schedules on YouTube
451
629
 
452
630
  ### LinkedIn
453
- - `visibility` - PUBLIC, CONNECTIONS, LOGGED_IN, CONTAINER
631
+ - `visibility` / `linkedin_visibility` - PUBLIC, CONNECTIONS, LOGGED_IN, CONTAINER
454
632
  - `target_linkedin_page_id` - Page ID for organization posts
633
+ - `linkedin_alt_text` - Alt text per image (string, JSON list, or repeated)
634
+ - `linkedin_disable_reshare` - Disable reshare by others
635
+ - `linkedin_link_title` / `linkedin_link_description` / `linkedin_thumbnail_alt_text` - Article/link-share overrides
636
+ - `linkedin_target_geo_locations` / `linkedin_target_industries` / `linkedin_target_seniorities` / `linkedin_target_job_functions` / `linkedin_target_staff_count_ranges` / `linkedin_target_interface_locales` / `linkedin_target_degrees` / `linkedin_target_fields_of_study` / `linkedin_target_organizations` - Page targeting (needs `target_linkedin_page_id`)
637
+ - `linkedin_target_entities` - Raw targeting JSON instead of the fields above
638
+ - `linkedin_target_check_audience` - Reject if LinkedIn reports fewer than 300 followers in the segment
639
+ - `linkedin_subtitles` / `linkedin_subtitles_url` / `linkedin_subtitles_text` - English SRT captions on video
455
640
 
456
641
  ### Facebook
457
642
  - `facebook_page_id` - Facebook Page ID (required)
@@ -459,13 +644,25 @@ for the music, location, cover and draft options.
459
644
  - `facebook_media_type` - REELS, STORIES, or VIDEO (normal page video)
460
645
  - `thumbnail_url` - Thumbnail URL for normal page videos (only when `facebook_media_type` is VIDEO)
461
646
  - `facebook_link_url` - URL for text posts
647
+ - `facebook_alt_text` - Alt text per photo (string, `facebook_alt_text[]`, or JSON array)
648
+ - `facebook_place_id` - Place id on feed/photos/videos/reels
649
+ - `facebook_targeting` / `facebook_feed_targeting` - JSON audience objects
650
+ - `facebook_call_to_action` / `facebook_child_attachments` / `facebook_multi_share_end_card` - Link post CTA and carousel
651
+ - `facebook_is_ai_generated` - AI-generated flag on Reels
652
+ - `facebook_collaborators` - Page ids to invite on Reels
653
+ - `facebook_unpublished_content_type` - DRAFT / INLINE_CREATED / ADS_POST on page video (`SCHEDULED` is rejected; use `scheduled_date`)
654
+ - `facebook_no_story` / `facebook_secret` - Page video flags
462
655
 
463
656
  ### Pinterest
464
657
  - `pinterest_board_id` - Board ID
465
658
  - `pinterest_link` - Destination link
466
659
  - `pinterest_alt_text` - Alt text for photos
467
660
  - `pinterest_cover_image_url` - Cover image URL (video)
468
- - `pinterest_cover_image_key_frame_time` - Key frame time in ms
661
+ - `pinterest_cover_image_key_frame_time` - Key frame time in seconds (values larger than the video duration are treated as milliseconds)
662
+ - `pinterest_board_section_id` - Board section id
663
+ - `pinterest_ai_disclosures` - `AI_MODIFIED` and/or `SYNTHETIC_PERFORMER`
664
+ - `pinterest_carousel_titles` / `pinterest_carousel_descriptions` / `pinterest_carousel_links` - Per-slide carousel fields (2–5 photos)
665
+ - `pinterest_carousel_index` - 0-based cover slide
469
666
 
470
667
  ### X (Twitter)
471
668
  - `reply_settings` - everyone, following, mentionedUsers, subscribers, verified
@@ -481,15 +678,30 @@ for the music, location, cover and draft options.
481
678
  - `card_uri` - Card URI for Twitter Cards
482
679
  - `x_long_text_as_post` - Post long text as single post
483
680
  - `x_thread_image_layout` - Comma-separated image layout for thread (e.g. "4,4" or "2,3,1"). Each value 1-4, total must equal image count. Auto-chunks into groups of 4 when >4 images.
681
+ - `x_alt_text` - Alt text (string, `x_alt_text[]`, or JSON array; ≤1000 chars)
682
+ - `x_subtitles` / `x_subtitles_url` / `x_subtitles_language` / `x_subtitles_name` - Video SRT captions
683
+ - `x_paid_partnership` - Paid partnership flag on the first post
684
+ - `x_article_title` / `x_article_body` / `x_article_content_state` / `x_article_draft` / `x_article_cover_media` - X Articles (text; Premium)
484
685
 
485
686
  ### Threads
486
- - `threads_long_text_as_post` - Post long text as single post (vs thread)
487
- - `threads_thread_media_layout` - Comma-separated list of how many media items to include in each Threads post (e.g. "5,5" or "3,4,3"). Each value 1-10, total must equal media count. Auto-chunks into groups of 10 when >10 items.
687
+ - `threads_long_text_as_post` - Post long text as single post (vs thread). Over 500 UTF-8 bytes this sends an official long post instead of truncating.
688
+ - `threads_thread_media_layout` - Comma-separated list of how many media items to include in each Threads post (e.g. "5,5" or "3,4,3"). Each value 0-20, total must equal media count. Auto-chunks into groups of 20 when >20 items.
488
689
  - `threads_topic_tag` - Topic tag for the Threads post (1-50 characters, no periods or ampersands). One tag per post. Helps increase reach.
690
+ - `threads_reply_control` - Who can reply: `everyone`, `accounts_you_follow`, `mentioned_only`, `parent_post_author_only`, `followers_only`
691
+ - `threads_alt_text` - Alt text per image/video (`threads_alt_text[]`)
692
+ - `threads_reply_to_id` / `threads_quote_post_id` - Reply or quote
693
+ - `threads_link_attachment` - Force link preview (text)
694
+ - `threads_poll_options` - 2–4 poll options (text)
695
+ - `threads_auto_publish_text` - Skip the second publish call on text posts
489
696
 
490
697
  ### Reddit
698
+ Reddit uploads currently return `error_code=reddit_unavailable` until the Reddit app is restored.
699
+
491
700
  - `subreddit` - Subreddit name (without r/)
492
701
  - `flair_id` - Flair template ID
702
+ - `reddit_nsfw` / `reddit_spoiler` / `reddit_resubmit` / `reddit_send_replies` - Booleans
703
+ - `reddit_flair_text` - Custom text for editable flairs
704
+ - `reddit_gallery_captions` / `reddit_gallery_urls` - Per-image gallery caption and outbound URL
493
705
 
494
706
  ### Google Business
495
707
  - `gbp_location_id` - Location, e.g. `"accounts/123/locations/456"` (list them with `get_google_business_locations`). Required when the account has more than one location; the API only auto-selects when exactly one exists.
@@ -500,6 +712,8 @@ for the music, location, cover and draft options.
500
712
  - `gbp_cta_type` / `gbp_cta_url` - Call-to-action button
501
713
  - `gbp_event_title` / `gbp_event_start_date` / `gbp_event_start_time` / `gbp_event_end_date` / `gbp_event_end_time` - Used with `gbp_topic_type="EVENT"`
502
714
  - `gbp_offer_coupon` / `gbp_offer_redeem_url` / `gbp_offer_terms` - Used with `gbp_topic_type="OFFER"`
715
+ - `gbp_coupon_code` / `gbp_redeem_url` / `gbp_terms` - Aliases of the offer fields above (legacy names still win if both are sent)
716
+ - `gbp_language_code` - BCP-47 language (default `en`)
503
717
 
504
718
  ```python
505
719
  locations = client.get_google_business_locations("my-profile")
@@ -515,6 +729,66 @@ client.upload_photos(
515
729
  )
516
730
  ```
517
731
 
732
+ ### Bluesky
733
+ - `bluesky_link_url` - External embed link preview (text)
734
+ - `bluesky_alt_text` - Alt text per image/video (JSON array, `||`-separated, or string)
735
+ - `bluesky_langs` - Comma list, max 3 BCP-47 codes
736
+ - `bluesky_labels` - `porn`, `sexual`, `nudity`, `graphic-media`
737
+ - `bluesky_gallery` - Publish up to 20 images as a gallery (`false` keeps the first 4)
738
+ - `bluesky_threadgate` / `bluesky_reply_settings` - Who can reply
739
+ - `bluesky_postgate` / `bluesky_quote_settings` - `disable_quotes` to block quotes
740
+ - `bluesky_quote_uri` / `bluesky_quote_id` / `bluesky_quote_url` - Quote another post
741
+
742
+ ### Discord
743
+ - `discord_thread_id` / `discord_thread_name` / `discord_applied_tags` - Thread or forum post
744
+ - `discord_embeds` / `discord_poll` / `discord_allowed_mentions` - JSON
745
+ - `discord_username` / `discord_avatar_url` - Per-post webhook identity
746
+ - `discord_alt_text` / `discord_flags` / `discord_tts` / `discord_max_file_mb`
747
+
748
+ ### Telegram
749
+ - `telegram_parse_mode` - `MarkdownV2` or `HTML`
750
+ - `telegram_message_thread_id` - Forum topic
751
+ - `telegram_disable_notification` / `telegram_protect_content` / `telegram_has_spoiler` / `telegram_pin`
752
+ - `telegram_link_preview` / `telegram_reply_markup` / `telegram_as_document`
753
+ - `telegram_caption_overflow` - `truncate` (default) or `split`
754
+ - `telegram_media_urls` - Comma-separated public URLs for a mixed album
755
+
756
+ ### Mastodon
757
+ - `mastodon_visibility` / `mastodon_sensitive` / `mastodon_spoiler_text` / `mastodon_language`
758
+ - `mastodon_alt_text` - `|`-separated for albums
759
+ - `mastodon_poll_options` / `mastodon_poll_expires_in` / `mastodon_poll_multiple`
760
+ - `mastodon_scheduled_at` - ISO 8601, at least 5 minutes ahead
761
+
762
+ ### WordPress
763
+ - `wordpress_status` / `wordpress_date` - `publish`, `draft`, `pending`, `future` (`date` required for `future`)
764
+ - `wordpress_categories` / `wordpress_tags` / `wordpress_excerpt` / `wordpress_slug`
765
+ - `wordpress_alt_text` / `wordpress_media_caption` / `wordpress_block_format`
766
+
767
+ ### Lemmy
768
+ - `lemmy_url` / `lemmy_community` / `lemmy_nsfw` / `lemmy_language_id` / `lemmy_alt_text`
769
+
770
+ ### Slack
771
+ - `slack_markdown` / `slack_mrkdwn` / `slack_blocks` / `slack_alt_text`
772
+ - `slack_first_comment_mode` - `separate` (default) or `inline`
773
+
774
+ ### Nostr
775
+ - `nostr_kind` - `1` default, `20` picture, `22` short video, `34235` video, `30023` long-form
776
+ - `nostr_long_form` - Shorthand for kind 30023
777
+
778
+ ### Dev.to
779
+ - `devto_tags` / `devto_canonical_url` / `devto_description` / `devto_main_image` / `devto_series` / `devto_published`
780
+
781
+ ### Hashnode
782
+ - `hashnode_body` / `content` - Article body
783
+ - `hashnode_tags` / `hashnode_original_article_url` / `hashnode_subtitle` / `hashnode_cover_image_url` / `hashnode_draft`
784
+
785
+ ### Whop
786
+ - `whop_body` / `whop_pinned` / `whop_is_mention` / `whop_paywall_amount` / `whop_paywall_currency` / `whop_attachment_ids`
787
+
788
+ ### Listmonk
789
+ - `listmonk_content_type` - `richtext` (default), `markdown`, `html`, `plain`
790
+ - `listmonk_send_at` / `listmonk_lists` / `listmonk_template_id` / `listmonk_media_ids`
791
+
518
792
  ## Common Options
519
793
 
520
794
  These options work across all upload methods:
@@ -525,6 +799,7 @@ These options work across all upload methods:
525
799
  | `user` | Profile name (required) |
526
800
  | `platforms` | Target platforms list (required) |
527
801
  | `first_comment` | First comment to post |
802
+ | `tiktok_first_comment` | First comment for TikTok only (needs the `comments` capability) |
528
803
  | `alt_text` | Alt text for accessibility |
529
804
  | `scheduled_date` | ISO date for scheduling |
530
805
  | `timezone` | Timezone for scheduled date |