syntax = "v1" type ( ThreadsAccountData { ID string `json:"id"` DisplayName string `json:"display_name,omitempty"` Username string `json:"username,omitempty"` ThreadsUserID string `json:"threads_user_id,omitempty"` PersonaID string `json:"persona_id,omitempty"` // deprecated: persona is chosen per publish, not bound to account BrowserConnected bool `json:"browser_connected"` ApiConnected bool `json:"api_connected"` APITokenExpiresAt int64 `json:"api_token_expires_at,omitempty"` Status string `json:"status"` CreateAt int64 `json:"create_at"` UpdateAt int64 `json:"update_at"` } ListThreadsAccountsData { List []ThreadsAccountData `json:"list"` ActiveAccountID string `json:"active_account_id"` } DeleteThreadsAccountData { DeletedID string `json:"deleted_id"` ActiveAccountID string `json:"active_account_id,omitempty"` Message string `json:"message"` } CreateThreadsAccountReq { DisplayName string `json:"display_name,optional"` Activate *bool `json:"activate,optional"` } UpdateThreadsAccountReq { DisplayName *string `json:"display_name,optional"` PersonaID *string `json:"persona_id,optional"` // deprecated: use persona_id in publish payload instead } ThreadsAccountPath { ID string `path:"id" validate:"required"` } ThreadsAccountConnectionPrefs { SearchViaApi bool `json:"search_via_api"` SearchSourceMode string `json:"search_source_mode"` PublishViaApi bool `json:"publish_via_api"` DevMode bool `json:"dev_mode"` ScrapeReplies bool `json:"scrape_replies"` RepliesPerPost int `json:"replies_per_post"` PublishHeaded bool `json:"publish_headed"` PlaywrightDebug bool `json:"playwright_debug"` } ThreadsAccountConnectionData { AccountID string `json:"account_id"` AccountName string `json:"account_name"` Username string `json:"username,omitempty"` BrowserConnected bool `json:"browser_connected"` ApiConnected bool `json:"api_connected"` Prefs ThreadsAccountConnectionPrefs `json:"prefs"` } UpdateThreadsAccountConnectionReq { SearchViaApi *bool `json:"search_via_api,optional"` SearchSourceMode *string `json:"search_source_mode,optional"` PublishViaApi *bool `json:"publish_via_api,optional"` DevMode *bool `json:"dev_mode,optional"` ScrapeReplies *bool `json:"scrape_replies,optional"` RepliesPerPost *int `json:"replies_per_post,optional"` PublishHeaded *bool `json:"publish_headed,optional"` PlaywrightDebug *bool `json:"playwright_debug,optional"` } ImportThreadsAccountSessionReq { StorageState string `json:"storageState" validate:"required"` } ImportThreadsAccountSessionData { Success bool `json:"success"` Valid bool `json:"valid"` Synced bool `json:"synced"` AccountID string `json:"account_id"` Username string `json:"username,omitempty"` Message string `json:"message"` UpdateAt int64 `json:"update_at"` } ThreadsAccountAiSettingsData { AccountID string `json:"account_id"` Provider string `json:"provider"` Model string `json:"model"` ResearchProvider string `json:"research_provider,omitempty"` ResearchModel string `json:"research_model,omitempty"` ApiKeys map[string]string `json:"api_keys"` ApiKeysConfigured map[string]interface{} `json:"api_keys_configured"` } UpdateThreadsAccountAiSettingsReq { Provider *string `json:"provider,optional"` Model *string `json:"model,optional"` ResearchProvider *string `json:"research_provider,optional"` ResearchModel *string `json:"research_model,optional"` ApiKeys map[string]string `json:"api_keys,optional"` } UpdateThreadsAccountHandlerReq { ThreadsAccountPath UpdateThreadsAccountReq } UpdateThreadsAccountConnectionHandlerReq { ThreadsAccountPath UpdateThreadsAccountConnectionReq } ImportThreadsAccountSessionHandlerReq { ThreadsAccountPath ImportThreadsAccountSessionReq } UpdateThreadsAccountAiSettingsHandlerReq { ThreadsAccountPath UpdateThreadsAccountAiSettingsReq } ThreadsAccountAiProviderPath { ID string `path:"id" validate:"required"` Provider string `path:"provider" validate:"required,oneof=opencode-go xai"` } ListThreadsAccountAiProviderModelsReq { ApiKey string `json:"api_key,optional"` // 選填;未帶則用已儲存的 key } ThreadsAccountAiProviderModelsHandlerReq { ThreadsAccountAiProviderPath ListThreadsAccountAiProviderModelsReq } ThreadsAccountAiProviderModelsData { ID string `json:"id"` Label string `json:"label"` Models []string `json:"models"` Streams bool `json:"streams"` Error string `json:"error,optional"` } StartThreadsOAuthQuery { AccountID string `form:"account_id,optional"` } StartThreadsOAuthData { AuthorizeURL string `json:"authorize_url"` State string `json:"state"` AccountID string `json:"account_id"` } ThreadsOAuthCallbackQuery { Code string `form:"code,optional"` State string `form:"state,optional"` Error string `form:"error,optional"` ErrorReason string `form:"error_reason,optional"` ErrorDescription string `form:"error_description,optional"` } ThreadsOAuthLogItem { At int64 `json:"at"` Level string `json:"level"` Stage string `json:"stage"` AccountID string `json:"account_id,omitempty"` Message string `json:"message"` } ListThreadsOAuthLogsData { List []ThreadsOAuthLogItem `json:"list"` } ThreadsOAuthConfigData { RedirectURI string `json:"redirect_uri"` SuccessRedirect string `json:"success_redirect"` Enabled bool `json:"enabled"` RequiresHTTPS bool `json:"requires_https"` } ThreadsAPISmokeTestItem { Scope string `json:"scope"` Name string `json:"name"` Status string `json:"status"` Message string `json:"message"` Count int `json:"count"` } RunThreadsAPISmokeTestData { List []ThreadsAPISmokeTestItem `json:"list"` Passed int `json:"passed"` Failed int `json:"failed"` Skipped int `json:"skipped"` Total int `json:"total"` } RunThreadsAPIPlaygroundReq { Action string `json:"action" validate:"required"` Query string `json:"query,optional"` Username string `json:"username,optional"` MediaID string `json:"media_id,optional"` ReplyID string `json:"reply_id,optional"` ReplyToID string `json:"reply_to_id,optional"` Text string `json:"text,optional"` LocationQuery string `json:"location_query,optional"` Limit int `json:"limit,optional"` Hide bool `json:"hide,optional"` SearchType string `json:"search_type,optional"` } RunThreadsAPIPlaygroundHandlerReq { ThreadsAccountPath RunThreadsAPIPlaygroundReq } ThreadsAPIPlaygroundData { Action string `json:"action"` Ok bool `json:"ok"` Message string `json:"message"` Data string `json:"data,optional"` } ListThreadsPostPerformanceQuery { Limit int `form:"limit,optional"` } ListThreadsPostPerformanceHandlerReq { ThreadsAccountPath ListThreadsPostPerformanceQuery } ThreadsPostMetricCapability { Scope string `json:"scope"` Name string `json:"name"` Metrics []string `json:"metrics"` Trackable bool `json:"trackable"` Note string `json:"note,optional"` } ThreadsInsightMetricItem { Name string `json:"name"` Value int `json:"value"` } ThreadsAccountInsightsBlock { Status string `json:"status"` Message string `json:"message,optional"` Metrics []ThreadsInsightMetricItem `json:"metrics,optional"` } ThreadsPostPerformanceItem { MediaID string `json:"media_id"` Text string `json:"text,optional"` Permalink string `json:"permalink,optional"` Timestamp string `json:"timestamp,optional"` LikeCount int `json:"like_count"` ReplyCount int `json:"reply_count"` RepostCount int `json:"repost_count,optional"` QuoteCount int `json:"quote_count,optional"` Views int `json:"views,optional"` Shares int `json:"shares,optional"` InsightsStatus string `json:"insights_status,optional"` InsightsMessage string `json:"insights_message,optional"` } ThreadsPostPerformanceData { AccountID string `json:"account_id"` Username string `json:"username,optional"` ThreadsUserID string `json:"threads_user_id,optional"` FetchedAt int64 `json:"fetched_at"` Capabilities []ThreadsPostMetricCapability `json:"capabilities"` AccountInsights ThreadsAccountInsightsBlock `json:"account_insights"` Posts []ThreadsPostPerformanceItem `json:"posts"` } PublishQueueItemPath { ID string `path:"id" validate:"required"` QID string `path:"qid" validate:"required"` } ListPublishQueueQuery { Status string `form:"status,optional"` Page int `form:"page,optional"` PageSize int `form:"pageSize,optional"` } ListPublishQueueHandlerReq { ThreadsAccountPath ListPublishQueueQuery } CreatePublishQueueReq { Text string `json:"text" validate:"required"` ScheduledAt int64 `json:"scheduled_at,optional"` } CreatePublishQueueHandlerReq { ThreadsAccountPath CreatePublishQueueReq } PatchPublishQueueReq { Text *string `json:"text,optional"` ScheduledAt *int64 `json:"scheduled_at,optional"` } PatchPublishQueueHandlerReq { PublishQueueItemPath PatchPublishQueueReq } PublishQueueItemData { ID string `json:"id"` AccountID string `json:"account_id"` PersonaID string `json:"persona_id,omitempty"` CopyMissionID string `json:"copy_mission_id,omitempty"` CopyDraftID string `json:"copy_draft_id,omitempty"` Text string `json:"text"` ScheduledAt int64 `json:"scheduled_at"` Status string `json:"status"` MediaID string `json:"media_id,optional"` Permalink string `json:"permalink,optional"` PublishedAt int64 `json:"published_at,optional"` ErrorMessage string `json:"error_message,optional"` RetryCount int `json:"retry_count,omitempty"` LastAttemptAt int64 `json:"last_attempt_at,omitempty"` NextAttemptAt int64 `json:"next_attempt_at,omitempty"` MissedAt int64 `json:"missed_at,omitempty"` PausedReason string `json:"paused_reason,omitempty"` CreateAt int64 `json:"create_at"` UpdateAt int64 `json:"update_at"` } PublishQueueListData { Pagination PaginationData `json:"pagination"` List []PublishQueueItemData `json:"list"` } ListThreadsPublishHealthQuery { Page int `form:"page,optional"` PageSize int `form:"pageSize,optional"` } ListThreadsPublishHealthHandlerReq { ThreadsAccountPath ListThreadsPublishHealthQuery } ThreadsPublishHealthSummary { PendingScheduled int64 `json:"pending_scheduled"` FailedCount int64 `json:"failed_count"` Published7d int64 `json:"published_7d"` TotalLikes7d int `json:"total_likes_7d"` TotalReplies7d int `json:"total_replies_7d"` } ThreadsPublishHealthCheckpoint { Checkpoint string `json:"checkpoint"` LikeCount int `json:"like_count"` ReplyCount int `json:"reply_count"` RepostCount int `json:"repost_count"` QuoteCount int `json:"quote_count"` Views int `json:"views,optional"` CheckedAt int64 `json:"checked_at"` } ThreadsPublishHealthItem { MediaID string `json:"media_id"` Permalink string `json:"permalink,optional"` Text string `json:"text,optional"` PublishedAt int64 `json:"published_at"` LikeCount int `json:"like_count"` ReplyCount int `json:"reply_count"` RepostCount int `json:"repost_count,optional"` QuoteCount int `json:"quote_count,optional"` Views int `json:"views,optional"` Shares int `json:"shares,optional"` Checkpoints []ThreadsPublishHealthCheckpoint `json:"checkpoints"` } ThreadsPublishHealthData { Summary ThreadsPublishHealthSummary `json:"summary"` Pagination PaginationData `json:"pagination"` List []ThreadsPublishHealthItem `json:"list"` } PublishSlotData { Weekday int `json:"weekday"` Time string `json:"time"` } PublishSourceRefData { Type string `json:"type"` PersonaID string `json:"persona_id,omitempty"` CopyMissionID string `json:"copy_mission_id,omitempty"` ScanPostID string `json:"scan_post_id,omitempty"` ManualSeed string `json:"manual_seed,omitempty"` } PublishInventoryPolicyData { AccountID string `json:"account_id"` Enabled bool `json:"enabled"` TargetDailyCount int `json:"target_daily_count"` LowStockThreshold int `json:"low_stock_threshold"` LookaheadDays int `json:"lookahead_days"` Timezone string `json:"timezone"` Slots []PublishSlotData `json:"slots"` SourceRefs []PublishSourceRefData `json:"source_refs"` UpdateAt int64 `json:"update_at"` } UpsertPublishInventoryPolicyReq { Enabled bool `json:"enabled"` TargetDailyCount int `json:"target_daily_count,optional"` LowStockThreshold int `json:"low_stock_threshold,optional"` LookaheadDays int `json:"lookahead_days,optional"` Timezone string `json:"timezone,optional"` Slots []PublishSlotData `json:"slots,optional"` SourceRefs []PublishSourceRefData `json:"source_refs,optional"` } UpsertPublishInventoryPolicyHandlerReq { ThreadsAccountPath UpsertPublishInventoryPolicyReq } StartPublishInventoryRefillJobReq { Count int `json:"count,optional"` } StartPublishInventoryRefillJobHandlerReq { ThreadsAccountPath StartPublishInventoryRefillJobReq } StartPublishInventoryRefillJobData { JobID string `json:"job_id"` Status string `json:"status"` Message string `json:"message"` } PublishSlotInsightData { Weekday int `json:"weekday"` Time string `json:"time"` AvgLikes1h int `json:"avg_likes_1h"` AvgReplies1h int `json:"avg_replies_1h"` AvgLikes24h int `json:"avg_likes_24h"` AvgReplies24h int `json:"avg_replies_24h"` AvgLikes7d int `json:"avg_likes_7d"` AvgReplies7d int `json:"avg_replies_7d"` SampleSize int `json:"sample_size"` Recommendation string `json:"recommendation"` } PublishSlotInsightsData { AccountID string `json:"account_id"` Timezone string `json:"timezone"` Slots []PublishSlotInsightData `json:"slots"` } PublishGuardPolicyData { AccountID string `json:"account_id"` Enabled bool `json:"enabled"` MaxDailyPosts int `json:"max_daily_posts"` MinIntervalMinutes int `json:"min_interval_minutes"` ConsecutiveFailurePauseLimit int `json:"consecutive_failure_pause_limit"` Paused bool `json:"paused"` PausedReason string `json:"paused_reason,omitempty"` UpdateAt int64 `json:"update_at"` } UpsertPublishGuardPolicyReq { Enabled bool `json:"enabled"` MaxDailyPosts int `json:"max_daily_posts,optional"` MinIntervalMinutes int `json:"min_interval_minutes,optional"` ConsecutiveFailurePauseLimit int `json:"consecutive_failure_pause_limit,optional"` Paused *bool `json:"paused,optional"` PausedReason string `json:"paused_reason,optional"` } UpsertPublishGuardPolicyHandlerReq { ThreadsAccountPath UpsertPublishGuardPolicyReq } PublishQueueEventData { ID string `json:"id"` QueueID string `json:"queue_id"` EventType string `json:"event_type"` FromStatus string `json:"from_status,omitempty"` ToStatus string `json:"to_status,omitempty"` Message string `json:"message,omitempty"` CreateAt int64 `json:"create_at"` } PublishQueueEventsData { List []PublishQueueEventData `json:"list"` } PublishAlertData { Type string `json:"type"` Severity string `json:"severity"` Message string `json:"message"` QueueID string `json:"queue_id,omitempty"` AccountID string `json:"account_id"` CreateAt int64 `json:"create_at"` } PublishAlertsData { List []PublishAlertData `json:"list"` } PublishQueueRangeQuery { StartAt int64 `form:"startAt,optional"` EndAt int64 `form:"endAt,optional"` Status string `form:"status,optional"` } PublishQueueRangeHandlerReq { ThreadsAccountPath PublishQueueRangeQuery } PublishDashboardAccountSummary { AccountID string `json:"account_id"` AccountName string `json:"account_name"` PendingScheduled int64 `json:"pending_scheduled"` FailedCount int64 `json:"failed_count"` Published7d int64 `json:"published_7d"` TotalLikes7d int `json:"total_likes_7d"` TotalReplies7d int `json:"total_replies_7d"` Paused bool `json:"paused"` BestSlot string `json:"best_slot,omitempty"` LowSlot string `json:"low_slot,omitempty"` } PublishDashboardSummaryData { List []PublishDashboardAccountSummary `json:"list"` TotalPending int64 `json:"total_pending"` TotalFailed int64 `json:"total_failed"` TotalPublished7d int64 `json:"total_published_7d"` TotalLikes7d int `json:"total_likes_7d"` TotalReplies7d int `json:"total_replies_7d"` } ThreadsDiagnosticsData { AccountID string `json:"account_id"` CheckedAt int64 `json:"checked_at"` ApiConnected bool `json:"api_connected"` TokenExpiresAt int64 `json:"token_expires_at,omitempty"` Scopes []string `json:"scopes"` Items []ThreadsAPISmokeTestItem `json:"items"` Message string `json:"message"` } ) @server( group: threads_account prefix: /api/v1/threads-accounts middleware: AuthJWT tags: "ThreadsAccount" summary: "Threads operating account endpoints. Requires Bearer JWT." ) service gateway { @handler listThreadsAccounts get / returns (ListThreadsAccountsData) @handler createThreadsAccount post / (CreateThreadsAccountReq) returns (ThreadsAccountData) @handler getThreadsAccount get /:id (ThreadsAccountPath) returns (ThreadsAccountData) @handler updateThreadsAccount patch /:id (UpdateThreadsAccountHandlerReq) returns (ThreadsAccountData) @handler deleteThreadsAccount delete /:id (ThreadsAccountPath) returns (DeleteThreadsAccountData) @handler activateThreadsAccount post /:id/activate (ThreadsAccountPath) @handler getThreadsAccountConnection get /:id/connection (ThreadsAccountPath) returns (ThreadsAccountConnectionData) @handler updateThreadsAccountConnection patch /:id/connection (UpdateThreadsAccountConnectionHandlerReq) returns (ThreadsAccountConnectionData) @handler importThreadsAccountSession post /:id/session/import (ImportThreadsAccountSessionHandlerReq) returns (ImportThreadsAccountSessionData) @handler getThreadsAccountAiSettings get /:id/ai-settings (ThreadsAccountPath) returns (ThreadsAccountAiSettingsData) @handler updateThreadsAccountAiSettings put /:id/ai-settings (UpdateThreadsAccountAiSettingsHandlerReq) returns (ThreadsAccountAiSettingsData) @handler listThreadsAccountAiProviderModels post /:id/ai-settings/providers/:provider/models (ThreadsAccountAiProviderModelsHandlerReq) returns (ThreadsAccountAiProviderModelsData) @handler startThreadsOauth get /oauth/start (StartThreadsOAuthQuery) returns (StartThreadsOAuthData) @handler listThreadsOauthLogs get /oauth/logs returns (ListThreadsOAuthLogsData) @handler getThreadsOauthConfig get /oauth/config returns (ThreadsOAuthConfigData) @handler disconnectThreadsApi post /:id/api/disconnect (ThreadsAccountPath) returns (ThreadsAccountData) @handler runThreadsApiSmokeTest post /:id/api/smoke-test (ThreadsAccountPath) returns (RunThreadsAPISmokeTestData) @handler runThreadsApiPlayground post /:id/api/playground (RunThreadsAPIPlaygroundHandlerReq) returns (ThreadsAPIPlaygroundData) @handler listThreadsPostPerformance get /:id/post-performance (ListThreadsPostPerformanceHandlerReq) returns (ThreadsPostPerformanceData) @handler createPublishQueueItem post /:id/publish-queue (CreatePublishQueueHandlerReq) returns (PublishQueueItemData) @handler listPublishQueueItems get /:id/publish-queue (ListPublishQueueHandlerReq) returns (PublishQueueListData) @handler getPublishQueueItem get /:id/publish-queue/:qid (PublishQueueItemPath) returns (PublishQueueItemData) @handler patchPublishQueueItem patch /:id/publish-queue/:qid (PatchPublishQueueHandlerReq) returns (PublishQueueItemData) @handler cancelPublishQueueItem post /:id/publish-queue/:qid/cancel (PublishQueueItemPath) returns (PublishQueueItemData) @handler deletePublishQueueItem delete /:id/publish-queue/:qid (PublishQueueItemPath) @handler listThreadsPublishHealth get /:id/publish-health (ListThreadsPublishHealthHandlerReq) returns (ThreadsPublishHealthData) @handler getPublishInventoryPolicy get /:id/publish-inventory-policy (ThreadsAccountPath) returns (PublishInventoryPolicyData) @handler upsertPublishInventoryPolicy put /:id/publish-inventory-policy (UpsertPublishInventoryPolicyHandlerReq) returns (PublishInventoryPolicyData) @handler startPublishInventoryRefillJob post /:id/publish-inventory/refill-jobs (StartPublishInventoryRefillJobHandlerReq) returns (StartPublishInventoryRefillJobData) @handler getPublishSlotInsights get /:id/publish-slot-insights (ThreadsAccountPath) returns (PublishSlotInsightsData) @handler getPublishGuardPolicy get /:id/publish-guard-policy (ThreadsAccountPath) returns (PublishGuardPolicyData) @handler upsertPublishGuardPolicy put /:id/publish-guard-policy (UpsertPublishGuardPolicyHandlerReq) returns (PublishGuardPolicyData) @handler resumePublishGuard post /:id/publish-guard/resume (ThreadsAccountPath) returns (PublishGuardPolicyData) @handler retryPublishQueueItem post /:id/publish-queue/:qid/retry (PublishQueueItemPath) returns (PublishQueueItemData) @handler listPublishQueueEvents get /:id/publish-queue/:qid/events (PublishQueueItemPath) returns (PublishQueueEventsData) @handler listPublishAlerts get /:id/publish-alerts (ThreadsAccountPath) returns (PublishAlertsData) @handler listPublishQueueRange get /:id/publish-calendar (PublishQueueRangeHandlerReq) returns (PublishQueueListData) @handler getThreadsDiagnostics get /:id/diagnostics (ThreadsAccountPath) returns (ThreadsDiagnosticsData) @handler getPublishDashboardSummary get /publish-dashboard-summary returns (PublishDashboardSummaryData) } @server( group: threads_account prefix: /api/v1/threads-accounts tags: "ThreadsAccount" summary: "Threads OAuth callback (public redirect from Meta)." ) service gateway { @handler threadsOauthCallback get /oauth/callback (ThreadsOAuthCallbackQuery) }