Skill: tfcbot/ai-ugc (version 0.0.4)

--- name: rawugc-api description: Call the RawUGC API to generate AI videos/images/music, manage content (personas, products, styles, characters), schedule social media posts, research TikTok content, and analyze viral videos. Use when the user wants to interact with any RawUGC API endpoint. requires: env: - RAWUGC_API_KEY compatibility: Requires RAWUGC_API_KEY (Bearer token for https://rawugc.com/api/v1). Obtain from RawUGC dashboard. homepage: https://github.com/tfcbot/rawugc-skills source: https://github.com/tfcbot/rawugc-skills --- # RawUGC API Procedural knowledge for agents to call the RawUGC API. All requests require an API key from the RawUGC dashboard, passed via environment variable. ## Authentication - **Environment variable**: Read the API key from `RAWUGC_API_KEY`. The key is created in the RawUGC dashboard and must be kept secret; do not hardcode or log it. - **Header**: Send on every request: `Authorization: Bearer <value of RAWUGC_API_KEY>`. - If `RAWUGC_API_KEY` is missing or empty, inform the user they must set it and obtain a key from the RawUGC dashboard. ## Base URL - **Production**: `https://rawugc.com/api/v1` - All paths below are relative to this base. ## API Versioning RawUGC uses date-based API versioning. The current latest version is `2026-03-06`. - **`RawUGC-Version` request header**: Override the version per-request (recommended). - **API key pinned version**: Set when creating the key in the dashboard. - **Fallback**: Latest version (`2026-03-06`) if neither is set. Always send `RawUGC-Version: 2026-03-06` in requests to ensure consistent behavior. --- ## Video Generation ### POST /videos/generate Initiate video generation. **Request body (JSON)**: | Field | Type | Required | Description | |-------|------|----------|-------------| | `model` | string | Yes | `sora-2-text-to-video`, `sora-2-image-to-video`, `kling-2.6/motion-control`, `veo3`, `veo3_fast` | | `prompt` | string | For text-to-video / veo3 | Text description (1-5000 chars) | | `imageUrls` | string[] | For image-to-video / kling | URLs, max 10. Veo3/veo3_fast accept up to 2 optional images. | | `videoUrls` | string[] | For kling | URLs, max 1. Required for `kling-2.6/motion-control` | | `aspectRatio` | string | No | Sora: `portrait`/`landscape`. Veo3: `16:9`/`9:16`/`Auto` | | `nFrames` | string | No | `"10"` or `"15"` (Sora only) | | `selectedCharacter` | string | No | Character username (e.g. `rawugc.mia`) | | `characterOrientation` | string | No | `image` or `video` (kling only) | | `mode` | string | No | `720p` or `1080p` (kling only) | **Response (201)**: `videoId`, `model`, `status`, `creditsUsed`, `newBalance`, `estimatedCompletionTime`, `createdAt`. ### GET /videos/:videoId Get video status. Returns `videoId`, `status`, `model`, `prompt`, `creditsUsed`, `url` (when completed), `createdAt`, `completedAt`, `failCode`, `failMessage`, `versions` (edit history array). ### GET /videos List videos. Query: `status`, `limit` (1-100, default 50), `page`. Returns `videos` array + `pagination`. ### POST /videos/captions Add styled captions to a completed video. Costs 1 credit. | Field | Type | Required | Description | |-------|------|----------|-------------| | `videoId` | string | Yes | Video identifier (vid_xxx) | | `language` | string | No | Language code (e.g. `en`). Defaults to auto-detect | **Response (200)**: `videoId`, `url`, `version`, `operation`, `creditsUsed`. ### POST /videos/overlay Add text overlay to a completed video. | Field | Type | Required | Description | |-------|------|----------|-------------| | `videoId` | string | Yes | Video identifier (vid_xxx) | | `text` | string | Yes | Overlay text (1-500 chars) | | `position` | string | No | `top`, `center`, or `bottom` | | `fontSize` | integer | No | 8-200 pixels | | `topBottomMargin` | integer | No | 0-500 pixels | | `strokeThickness` | number | No | 0-10 | **Response (200)**: `videoId`, `url`, `version`, `operation`, `creditsUsed`. --- ## Image Generation ### POST /images/generate Generate AI images using Nano Banana models. Async -- poll GET /images/:imageId. | Field | Type | Required | Description | |-------|------|----------|-------------| | `model` | string | Yes | `nano-banana-2` (text-to-image, 4 credits) or `google/nano-banana-edit` (image editing, 2 credits) | | `prompt` | string | Yes | Text description or edit instruction (1-20000 chars) | | `imageUrls` | string[] | For editing | Source images. Required for `google/nano-banana-edit`. Optional for `nano-banana-2` (reference images, max 14). | | `aspectRatio` | string | No | For `nano-banana-2`: `1:1`, `16:9`, `9:16`, `auto`, etc. | | `imageSize` | string | No | For `google/nano-banana-edit`: `1:1`, `16:9`, `9:16`, `auto`, etc. | | `resolution` | string | No | For `nano-banana-2`: `1K`, `2K`, `4K` | | `outputFormat` | string | No | `png`, `jpeg`, `jpg` | | `googleSearch` | boolean | No | Use Google Web Search grounding (`nano-banana-2` only) | **Response (201)**: `imageId`, `model`, `status`, `creditsUsed`, `newBalance`, `estimatedCompletionTime`, `createdAt`. ### GET /images/:imageId Get image status. Returns `imageId`, `status`, `model`, `prompt`, `url` (when completed), `imageSize`, `resolution`, `outputFormat`, `creditsUsed`, `createdAt`, `completedAt`, `failCode`, `failMessage`. ### GET /images List images. Query: `status`, `limit` (1-100, default 20), `page`. Returns `images` array + `pagination`. --- ## Music Generation ### POST /music/generate Generate AI music using Suno models. 3 credits per generation. Async -- poll GET /music/:musicId. | Field | Type | Required | Description | |-------|------|----------|-------------| | `prompt` | string | Yes | Music description (1-2000 chars) | | `model` | string | No | `V3_5`, `V4`, `V4_5`, `V4_5PLUS`, `V4_5ALL`, `V5` (default: `V5`) | | `instrumental` | boolean | No | Instrumental only, no vocals (default: true) | | `title` | string | No | Track title (max 200 chars). Enables custom mode with `style`. | | `style` | string | No | Style descriptor (max 500 chars, e.g. `lo-fi hip hop`) | **Response (201)**: `musicId`, `model`, `status`, `creditsUsed`, `newBalance`, `estimatedCompletionTime`, `createdAt`. ### GET /music/:musicId Get music status. Returns `musicId`, `status`, `model`, `prompt`, `audioUrl` (when completed), `albumArtUrl`, `duration`, `title`, `creditsUsed`, `createdAt`, `completedAt`, `failCode`, `failMessage`. ### GET /music List music tracks. Query: `status`, `limit` (1-100, default 20), `page`. Returns `tracks` array + `pagination`. --- ## Upload ### POST /upload Upload a video or image file. Returns a URL for use in generation requests (`imageUrls`, `videoUrls`) or `analyze-video`. Max 100MB. **Request**: `multipart/form-data` with `file` field. Accepted types: `video/mp4`, `video/quicktime`, `video/webm`, `image/png`, `image/jpeg`, `image/webp`. **Response (200)**: `url`, `contentType`, `size`. --- ## Characters ### GET /characters List all available AI characters (built-in + custom). Returns `characters` array, `count`, `adminCount`, `userCount`. ### GET /characters/:characterId Get a character by ID. Returns `_id`, `username`, `displayName`, `description`, `videoPreviewUrl`, `type` (`admin`/`user`), `isActive`, `createdAt`, `updatedAt`. --- ## Personas (CRUD) Personas define target audiences for content plan generation. - **GET /personas** -- List all. Returns `personas` array + `count`. - **POST /personas** -- Create. Body: `name` (required, max 200), `description` (required, max 5000). Returns `id`. - **GET /personas/:personaId** -- Get one. - **PATCH /personas/:personaId** -- Update. Body: `name`, `description` (both optional). - **DELETE /personas/:personaId** -- Delete. **PersonaResponse**: `_id`, `organizationId`, `name`, `description`, `createdAt`, `updatedAt`. --- ## Messaging (CRUD) Brand/positioning messaging templates. - **GET /messaging** -- List all. Returns `messages` array + `count`. - **POST /messaging** -- Create. Body: `name` (required, max 200), `body` (required, max 5000). Returns `id`. - **GET /messaging/:messageId** -- Get one. - **PATCH /messaging/:messageId** -- Update. Body: `name`, `body` (both optional). - **DELETE /messaging/:messageId** -- Delete. **MessagingResponse**: `_id`, `organizationId`, `name`, `body`, `createdAt`, `updatedAt`. --- ## Products (CRUD) Products for video generation. - **GET /products** -- List all. Returns `products` array + `count`. - **POST /products** -- Create. Body: `name` (required, max 200), `photos` (required, URL array), `description` (max 1000), `messaging` (max 5000). Returns `id`. - **GET /products/:productId** -- Get one. - **PATCH /products/:productId** -- Update. Body: `name`, `description`, `photos`, `messaging` (all optional). - **DELETE /products/:productId** -- Delete. **ProductResponse**: `_id`, `name`, `description`, `photos`, `messaging`, `createdAt`, `updatedAt`. --- ## Styles (CRUD) Video/image creative styles with optional prompt templates. - **GET /styles** -- List all (built-in + custom). Query: `type` (`video`/`image`). Returns `styles` array + `count`. - **POST /styles** -- Create. Body: `name` (required, max 200), `description` (max 1000), `type` (`video`/`image`), `aspectRatio` (`portrait`/`landscape`/`square`), `promptTemplate` (max 5000, supports `{productName}`, `{messaging}`, `{character}` placeholders). Returns `id`. - **GET /styles/:styleId** -- Get one. - **PATCH /styles/:styleId** -- Update. All fields optional. - **DELETE /styles/:styleId** -- Delete. **StyleResponse**: `_id`, `name`, `description`, `type`, `aspectRatio`, `styleId`, `promptTemplate`, `isAdmin`, `isStandard`. --- ## Social Scheduling ### GET /social/accounts List connected social accounts (max 3 per org). Returns `accounts` array + `count`. Each account: `accountId`, `platform` (`tiktok`/`instagram`/`youtube`), `username`, `displayName`, `profilePicture`, `isActive`. ### POST /social/accounts Sync connected accounts from the scheduling provider. Returns `{ success: boolean }`. ### DELETE /social/accounts/:accountId Disconnect a social account. Returns `{ success: boolean }`. ### POST /social/posts Schedule, draft, or immediately publish a video to social media. | Field | Type | Required | Description | |-------|------|----------|-------------| | `videoUrl` | string | Yes | URL of video to post | | `accountIds` | string[] | Yes | Target account IDs | | `mode` | string | Yes | `schedule`, `draft`, or `now` | | `scheduledFor` | integer | For schedule | Unix timestamp (ms) | | `timezone` | string | No | IANA timezone (default: `UTC`) | | `content` | string | No | Caption (max 2200 chars) | | `videoId` | string | No | RawUGC video ID to link | | `publishToInbox` | boolean | No | Send to TikTok Creator Inbox | | `tiktokPrivacyLevel` | string | No | `SELF_ONLY`, `PUBLIC_TO_EVERYONE`, `MUTUAL_FOLLOW_FRIENDS`, `FOLLOWER_OF_CREATOR` | | `tiktokAllowComment` | boolean | No | Allow TikTok comments | | `tiktokAllowDuet` | boolean | No | Allow TikTok duets | | `tiktokAllowStitch` | boolean | No | Allow TikTok stitches | | `tiktokCommercialContentType` | string | No | `none`, `brand_organic`, `brand_content` | **Response (201)**: SocialPost object. ### GET /social/posts List posts. Query: `fromDate` (ms), `toDate` (ms), `includeDrafts` (boolean). Returns `posts` array + `count`. ### GET /social/posts/:postId Get a post. ### PATCH /social/posts/:postId Update a post. Body: `content`, `scheduledFor`, `timezone`, `accountIds` (at least one field required). ### DELETE /social/posts/:postId Delete a post. Returns `{ success: boolean }`. ### POST /social/posts/:postId/reschedule Reschedule a post. Body: `scheduledFor` (required, ms), `timezone`. ### POST /social/posts/:postId/publish Immediately publish a draft post. **SocialPost**: `postId`, `platforms`, `status` (`draft`/`scheduled`/`published`/`failed`), `scheduledFor`, `timezone`, `content`, `videoUrl`, `createdAt`, `publishedAt`. --- ## Viral Library ### GET /viral-library/videos/:videoId Get a viral library video with full AI analysis (hooks, keyframes, performance insights). Returns ViralLibraryVideo. ### GET /viral-library/search Semantic search across analyzed videos. Query: `q` (required, natural language), `limit` (1-50, default 20). Returns `results` (array of `{ video, score }`), `query`, `total`. --- ## Research ### POST /scrape-tiktok Scrape TikTok videos. Costs 3 credits. | Field | Type | Required | Description | |-------|------|----------|-------------| | `query` | string | Yes | Search keyword, hashtag, or query (max 500) | | `mode` | string | No | `keyword`, `hashtag`, `search` (default: `keyword`) | | `limit` | integer | No | 1-10 (default: 10) | **Response (200)**: `scrapeId` (use with content-plans), `count`, `videos` (array with `id`, `url`, `author`, `description`, `stats`, `duration`, `hashtags`, `thumbnail`, `videoUrl`). ### POST /content-plans Generate a content plan from scraped videos. Costs 3 credits. | Field | Type | Required | Description | |-------|------|----------|-------------| | `scrapeId` | string | Yes | From scrape-tiktok response | | `brief` | string | Yes | Content plan goals (max 5000) | **Response (200)**: `planId`, `scrapeId`, `brief`, `topWins`, `gapsToTest`, `blueprints` (array with `category`, `strategy`, `evidence`, `contentIdeas`). ### GET /content-plans List all content plans. Returns `plans` array + `count`. ### POST /analyze-video Analyze any video URL (social links or direct URLs). Costs 1 credit. Max 150MB. | Field | Type | Required | Description | |-------|------|----------|-------------| | `videoUrl` | string | Yes | Video URL to analyze | | `prompt` | string | No | Custom analysis prompt (max 5000) | **Response (200)**: `summary`, `hook`, `keyframes` (array with `timestamp`, `type`, `description`, `visual`, `audio`, `text`), `durationSeconds`, `tags`, `whyItPerformed`, `attributesToCopy`, `hooksToTest`. --- ## Errors All error responses use RFC 7807 Problem Details (JSON): `type`, `title`, `status`, `detail`, `instance`, `errors`. | Status | Meaning | |--------|---------| | 400 | Validation error. Surface `detail` and `errors` to user. | | 401 | Auth error. Check `RAWUGC_API_KEY`. | | 402 | Insufficient credits. Add credits in dashboard. | | 403 | Insufficient scope. API key lacks permissions. | | 404 | Resource not found. | | 429 | Rate limit exceeded. Check `X-RateLimit-Reset` header. | | 500 | Server error. Retry or contact support. | ## Rate Limits - API Key: 10 req/min. Session: 20 req/min. - Headers: `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset` (unix timestamp). ## Workflow: Generate then poll 1. **Generate**: POST to the generation endpoint. Note the returned ID (`videoId`/`imageId`/`musicId`). 2. **Poll**: GET the status endpoint periodically (10-30s). Use exponential backoff. 3. **Finish**: When `status === 'completed'`, use the result URL. When `failed`, surface error to user. 4. **Edit** (video only): POST to `/videos/captions` or `/videos/overlay`. For full request/response shapes, see [reference.md](reference.md).


Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (CRITICAL)