API Reference
The PostQuickAI API is organized around REST. It accepts JSON-encoded request bodies, returns JSON-encoded responses, and uses standard HTTP response codes, authentication, and verbs.
Use the API to generate AI content, create and manage posts, publish to social platforms, schedule posts, generate images and videos — everything available in the dashboard, fully programmable.
The API is designed for developers building integrations, automations, and AI agents that manage social media workflows at scale.
Base URL
https://www.postquick.ai/apiClient Libraries
Use any HTTP client. The API returns standard JSON — no SDK required. Works with cURL, Python requests, JavaScript fetch, and any AI agent framework.
Authentication
The PostQuickAI API uses API keys to authenticate requests. Include your key in the Authorization header as a Bearer token.
API keys carry full access to your account. Keep them secure — don't share them in client-side code, public repositories, or logs.
All requests must be made over HTTPS. Requests without authentication return 401.
Create and manage keys in your API Dashboard.
curl https://www.postquick.ai/api/v1/content-groups \ -H "Authorization: Bearer pq_live_your_key_here"
Base URL
All API endpoints are relative to the base URL. All requests use the /api/v1 prefix for the current API version.
Important: Always use www.postquick.ai — requests to the bare domain are redirected, which strips the Authorization header.
https://www.postquick.ai/api/v1Response Format
All responses return a consistent JSON structure. Successful responses contain a success boolean and a data object.
Error responses contain an error object with a machine-readable code and human-readable message.
{
"success": true,
"data": {
"post": {
"id": "abc123",
"content": "Just shipped a new feature...",
"status": "pending",
"post_type": "text"
}
}
}{
"success": false,
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded. Try again in 45 seconds.",
"details": { "retryAfter": 45 }
}
}Errors
PostQuickAI uses conventional HTTP response codes. Codes in the 2xx range indicate success. 4xx codes indicate client errors (bad request, auth failure, limit exceeded). 5xx codes indicate server errors (rare).
When a request fails, check the error.code field for the specific error type and implement retry logic where appropriate (e.g., exponential backoff for rate limits).
| Code | Description |
|---|---|
| 200 | OK — Request succeeded. |
| 201 | Created — Resource was created. |
| 202 | Accepted — Async operation started (video generation, publishing). |
| 400 | Bad Request — Missing or invalid parameters. |
| 401 | Unauthorized — Invalid or missing API key. |
| 403 | Forbidden — Subscription inactive, API not enabled, or limit exceeded. |
| 404 | Not Found — Resource doesn't exist. |
| 409 | Conflict — Resource is in a conflicting state (e.g., already processing). |
| 429 | Too Many Requests — Rate limit exceeded. Check Retry-After header. |
| 500 | Server Error — Something went wrong on our end. Retry with exponential backoff. |
Error Codes
The error.code field contains a machine-readable error identifier. Use this for programmatic error handling.
| MISSING_AUTH | No Authorization header provided. Add Bearer token to all requests. |
| INVALID_KEY_FORMAT | Key doesn't match expected format (pq_live_...). Check for typos. |
| INVALID_KEY | API key is invalid or has been revoked. Create a new key in the dashboard. |
| KEY_EXPIRED | API key has passed its expiration date. Keys are valid indefinitely unless revoked. |
| NO_SUBSCRIPTION | No active subscription found. Subscribe at postquick.ai/pricing. |
| SUBSCRIPTION_INACTIVE | Subscription is cancelled or expired. Renew to continue using the API. |
| API_NOT_ENABLED | API add-on has not been purchased. Enable in dashboard settings. |
| RATE_LIMIT_EXCEEDED | Per-minute or daily rate limit hit. Wait for retryAfter seconds. |
| LIMIT_EXCEEDED | Plan generation limit exceeded (images, text, videos). Upgrade or wait for reset. |
| NOT_FOUND | The requested resource was not found or you don't have access to it. |
| INTERNAL_ERROR | Unexpected server error. Retry the request. Contact support if it persists. |
{
"success": false,
"error": {
"code": "INVALID_KEY",
"message": "Invalid or revoked API key."
}
}Error Recovery Pattern
For rate limits (429), implement exponential backoff: start with a 1s delay, double on each retry (1s, 2s, 4s, 8s...), max 5 retries. Use the Retry-After header value if provided.
Rate Limits
Rate limits are applied per API key using a sliding window algorithm. Every response includes rate limit headers so you can track your usage in real-time.
Important: Your plan's content generation limits (images, text, videos) are shared between the dashboard and API. Rate limits control request throughput; generation limits control content volume.
When you hit a rate limit, the API returns 429 with a Retry-After header indicating seconds to wait. Implement exponential backoff for production apps.
| Plan | Per Minute | Per Day |
|---|---|---|
| Basic ($8/mo) | 30 requests | 5,000 requests |
| Pro ($20/mo) | 120 requests | 50,000 requests |
Response Headers
| X-RateLimit-Limit-Minute | Maximum requests per minute for your plan (30 for Basic, 120 for Pro). |
| X-RateLimit-Limit-Day | Maximum requests per day for your plan (5,000 for Basic, 50,000 for Pro). |
| Retry-After | Seconds to wait before retrying (only sent with 429 responses). Use this value for your backoff timer. |
{
"success": false,
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded. Try again in 45 seconds.",
"details": { "retryAfter": 45 }
}
}Rate Limit Headers Example
X-RateLimit-Limit-Minute: 120 X-RateLimit-Limit-Day: 50000
Object Schemas
The API works with three core object types: Post (text/image/carousel posts), Video Post (AI-generated videos), and Content Group (brands/accounts). Below are the complete schemas with every field documented.
The Post Object
idUnique identifier for the post (UUID).
contentThe post caption/text. May include hashtags and emojis.
statusOne of:
"draft", "pending", "posted", "scheduled", "failed", "processing", "published".post_typeOne of:
"text", "image", "carousel", "video".app_idThe content group (brand) this post belongs to (UUID).
platformsposted_platformsPlatforms this post has been successfully published to.
image_urlPublic URL of a single image (for
post_type: "image").image_urlsArray of image URLs (for
post_type: "carousel"). 2-10 images.video_urlPublic URL of a video (for
post_type: "video").is_manualTrue if created via API or manual upload, false if AI-generated via
/posts/generate.scheduled_forISO 8601 timestamp for scheduled publishing. Null if not scheduled.
error_messageHuman-readable error description when status is
"failed".created_atISO 8601 timestamp when the post was created.
updated_atISO 8601 timestamp when the post was last updated.
posted_atISO 8601 timestamp when the post was actually published to platforms.
photo_cover_indexIndex of the cover image for TikTok carousel posts (0-based). Only relevant for carousel posts published to TikTok.
platform_post_idsPlatform-specific post IDs for analytics. Keyed by platform name (e.g. twitter_x, instagram, tiktok). Populated after publish.
linkedin_targetLinkedIn publish target:
{ type: "personal" | "organization", organizationId?: string }. Required when publishing to LinkedIn.facebook_targetFacebook page target:
{ pageId: string, pageName?: string }. Required when publishing to Facebook.thread_partsArray of thread parts for multi-post threads (Twitter/X):
[{ text: string, image_urls?: string[], video_url?: string, post_type: string }].The Video Post Object
idUnique identifier for the video post (UUID).
app_idThe content group (brand) this video belongs to (UUID).
user_idUser ID who created this video (UUID).
titleDisplay title for the video (shown in dashboard, not published).
descriptionThe generation prompt used to create the video.
statusOne of:
"pending" (queued), "generating" (in progress, 2-10 min), "completed" (ready), "failed", "scheduled", "processing" (publishing), "posted".video_urlPublic URL of the raw generated video. Available when status is
"completed".optimized_video_urlPublic URL of the preprocessed video (transcoded for platform compatibility). Used for publishing. Falls back to
video_url if preprocessing was skipped.durationVideo duration in seconds (4, 6, 8, or 12 depending on model).
platformsTarget platforms for publishing.
posted_platformsPlatforms this video has been successfully published to.
scheduled_forISO 8601 timestamp for scheduled publishing.
error_messageHuman-readable error description when status is
"failed".created_atISO 8601 timestamp when the video generation was started.
updated_atISO 8601 timestamp when the video was last updated.
The Content Group Object
idUnique identifier for the content group (UUID).
user_idUser ID who owns this content group (UUID).
nameDisplay name for the content group (e.g., "My Brand", "Client A").
descriptionOptional description of the brand/account.
created_atISO 8601 timestamp when the content group was created.
app_platformsArray of platform objects:
[{ platform: "instagram" }, { platform: "twitter" }]. Indicates which platforms this group targets.social_accountsArray of connected social accounts:
[{ id: string, platform: string, account_name: string }]. Only accounts connected via OAuth.content_instructionsBrand profile used for AI generation:
{ brand_name, tone, target_audience, unique_angle, instructions, image_model, video_model, ... }. Shapes AI output for this group.Supported Platforms
PostQuickAI supports publishing to 7 social platforms. Each platform has specific requirements and constraints. Use these platform names in the platforms array when creating, publishing, or scheduling content.
instagramTwitter / X
twitterlinkedinfacebookTikTok
tiktokThreads
threadsBluesky
blueskyVideo Models
PostQuickAI supports multiple AI video generation models. Each model has different quality, speed, and credit costs. Specify the model in the model parameter when generating videos.
Video generation is asynchronous — the API returns 202 Accepted immediately, then processes the video in the background (2-10 minutes). Poll the /videos/:id/status endpoint to check progress.
| Model ID | Name | Credits | Durations | Provider |
|---|---|---|---|---|
| veo-3.1-fast-generate-preview | Google Veo 3.1 Fast | 1 | 4s, 6s, 8s | Google Fast generation (~2-4 min). Default model. |
| veo-3.1-generate-preview | Google Veo 3.1 | 3 | 4s, 6s, 8s | Google Higher quality, slower (~6-10 min). |
| sora-2 | OpenAI Sora 2 | 1 | 4s, 8s, 12s | OpenAI Realistic, cinematic quality. |
| sora-2-pro | OpenAI Sora 2 Pro | 3 | 4s, 8s, 12s | OpenAI Best quality, longest durations. |
Aspect Ratios
9:16— Portrait (TikTok, Reels, Shorts). Default.16:9— Landscape (YouTube, LinkedIn).1:1— Square (Instagram feed).
Image Models
PostQuickAI supports multiple AI image generation models. Each model has a different visual style and quality level. Specify the model in the model parameter when generating images.
All image generation consumes 1 image credit, regardless of model. Images are uploaded to cloud storage and returned as public URLs.
| Model ID | Description |
|---|---|
| gemini-flash | Google Gemini — fast generation, good quality, versatile. Default model. |
| gpt-image-1.5 | OpenAI GPT Image — high detail, accurate prompt following, excellent for complex scenes. |
| nano-banana-pro | Nano Banana Pro — premium photorealistic quality, stylized or realistic. Great for product shots, portraits, and creative content. |
Workflows
Below are complete end-to-end workflows showing how to combine API endpoints for common use cases. These examples show the full request/response cycle.
Workflow 1: AI Content Pipeline
Generate brand-aligned content, review it, optionally edit, then publish to platforms.
POST /v1/content-groups with name, description, and platforms.POST /v1/posts/generate with contentGroupId. Optionally set generateImage: true.GET /v1/posts/:id to fetch the full post.PUT /v1/posts/:id to update content, platforms, etc.POST /v1/content/adjust-tone, /proofread, /make-concise to refine via AI.POST /v1/posts/:id/publish with platforms array.Workflow 2: Video Generation Pipeline
Generate an AI video, wait for it to complete, then publish to TikTok and Instagram Reels.
POST /v1/videos/generate with prompt, contentGroupId, model, aspectRatio, duration.GET /v1/videos/:id/status every 10-30 seconds.GET /v1/videos/:id to fetch complete video post with URLs, duration, metadata.POST /v1/videos/:id/publish with platforms: ["instagram", "tiktok"].Workflow 3: Scheduled Content Calendar
Batch-create content for the week, schedule posts for specific times, and let the cron system auto-publish.
POST /v1/posts/generate or POST /v1/posts/create multiple times to build your content queue.POST /v1/posts/:id/schedule with scheduledFor (ISO 8601 timestamp, must be in future) + platforms array.GET /v1/posts?contentGroupId=...&status=scheduled to see upcoming posts.GET /v1/posts?contentGroupId=...&status=posted to see published posts.Async Operations
Several API operations are asynchronous because they involve long-running processes (video generation, video publishing, platform API calls). The API returns 202 Accepted immediately, then processes the job in the background.
Why async? Video generation takes 2-10 minutes (AI model processing). Video publishing requires transcoding, platform uploads, and OAuth calls — 1-3 minutes. Without async, you'd hit request timeouts.
How to handle async operations:
Video Generation (POST /v1/videos/generate)
- Call
POST /v1/videos/generate→ receives202with video post object (status: "pending"). - Poll
GET /v1/videos/:id/statusevery 10-30 seconds. - When status is
"completed", video_url is ready. - If status is
"failed", check error_message. Credits are auto-refunded.
Video Publishing (POST /v1/videos/:id/publish)
- Call
POST /v1/videos/:id/publish→ receives202(job queued). - Cloud Run worker picks up the job, transcodes video (if needed), uploads to platforms.
- Poll
GET /v1/videos/:idto check posted_platforms array. - When posted_platforms contains your target platforms, publishing is complete.
Post Publishing
POST /v1/posts/:id/publish publishes immediately to the specified platforms and returns the result of that publish attempt, including successful platforms and any platform-specific errors.
List content groups
/v1/content-groupsReturns all content groups (brands/accounts) for the authenticated user, including connected platforms, social accounts, and content instructions.
Use this endpoint to discover available content groups before creating posts. The returned IDs are used in contentGroupId parameters throughout the API.
curl https://www.postquick.ai/api/v1/content-groups \ -H "Authorization: Bearer pq_live_your_key_here"
{
"success": true,
"data": {
"contentGroups": [
{
"id": "uuid-abc-123",
"name": "My Brand",
"description": "Tech startup social media",
"created_at": "2026-03-01T10:00:00Z",
"app_platforms": [
{ "platform": "instagram" },
{ "platform": "twitter" }
],
"social_accounts": [
{
"id": "sa-1",
"platform": "instagram",
"account_name": "@mybrand"
}
],
"content_instructions": {
"brand_name": "My Brand",
"tone": "professional",
"target_audience": "Tech founders",
"unique_angle": "Developer tools"
}
}
]
}
}Create a content group
/v1/content-groupsCreates a new content group (brand/account). Content groups organize your posts and define brand voice for AI generation. Subject to your plan's content group limit (5 for Basic, unlimited for Pro).
Social accounts must be connected separately via OAuth in the dashboard. The API only creates the content group structure.
Parameters
namestringrequiredDisplay name for the content group (e.g., "My Brand", "Client A").
descriptionstringOptional description of the brand/account.
platformsstring[]Array of platform names this group targets. See Supported Platforms.
curl -X POST https://www.postquick.ai/api/v1/content-groups \
-H "Authorization: Bearer pq_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"name": "My Brand",
"description": "Tech startup social media",
"platforms": ["instagram", "twitter", "linkedin"]
}'{
"success": true,
"data": {
"contentGroup": {
"id": "uuid-new-456",
"name": "My Brand",
"description": "Tech startup social media",
"created_at": "2026-03-25T14:30:00Z"
}
}
}Retrieve a content group
/v1/content-groups/:idRetrieves a single content group by ID, including platform connections, connected social accounts, and full content instructions. Returns 404 if the content group doesn't exist or you don't have access to it.
curl https://www.postquick.ai/api/v1/content-groups/uuid-abc-123 \ -H "Authorization: Bearer pq_live_your_key_here"
{
"success": true,
"data": {
"contentGroup": {
"id": "uuid-abc-123",
"name": "My Brand",
"description": "Tech startup social media",
"created_at": "2026-03-01T10:00:00Z",
"app_platforms": [
{ "platform": "instagram" },
{ "platform": "twitter" }
],
"social_accounts": [
{ "id": "sa-1", "platform": "instagram", "account_name": "@mybrand" }
],
"content_instructions": {
"brand_name": "My Brand",
"tone": "professional",
"target_audience": "Tech founders",
"unique_angle": "Developer tools",
"instructions": "Focus on product updates and thought leadership",
"image_model": "gemini-flash",
"video_model": "veo-3.1-fast-generate-preview"
}
}
}
}Delete a content group
/v1/content-groups/:idPermanently deletes a content group and all associated posts (via CASCADE). This cannot be undone. Social account connections are preserved (they can be reused in other content groups).
Returns 404 if the content group doesn't exist or you don't have permission to delete it.
curl -X DELETE https://www.postquick.ai/api/v1/content-groups/uuid-abc-123 \ -H "Authorization: Bearer pq_live_your_key_here"
{
"success": true,
"data": {
"message": "Content group deleted successfully"
}
}Get brand instructions
/v1/content-groups/:id/instructionsRetrieves the brand profile attached to a content group: brand name, target audience, tone, topics, auto-generation settings, YOLO mode config, and more. These instructions are used to ground every AI-generated post, caption, and image.
Returns instructions: null if no brand profile has been set for this group.
curl https://www.postquick.ai/api/v1/content-groups/uuid-abc-123/instructions \ -H "Authorization: Bearer pq_live_your_key_here"
{
"success": true,
"data": {
"instructions": {
"app_id": "uuid-abc-123",
"brand_name": "Acme Fitness",
"target_audience": "Busy professionals aged 25-40",
"tone": "Motivating, direct, no-nonsense",
"topics": "Home workouts, nutrition tips, mindset",
"instructions": "Always include a clear CTA...",
"include_image": true,
"image_model": "nano-banana-pro",
"auto_generate": false,
"yolo_mode": false,
"yolo_platforms": [],
"frequency": "daily",
...
}
}
}Update brand instructions
/v1/content-groups/:id/instructionsCreate or update the brand profile attached to a content group. This is an upsert — pass only the fields you want to set. All future AI generation for this group will be grounded in these instructions.
The brand profile drives caption quality significantly. Setting brand_name, target_audience, tone, and topics typically yields the biggest jump in output quality.
Parameters
brand_namestringThe brand or business name.
target_audiencestringWho the brand speaks to (e.g. "busy parents, 30-50").
tonestringVoice/tone guidance (e.g. "friendly and confident").
topicsstringTopics the brand covers.
instructionsstringFree-form guidance injected into every generation.
image_instructionsstringStyle guidance for image generation.
include_imagebooleanWhether auto-generated posts include images.
image_modelstring"gemini-flash" | "gpt-image-1.5" | "nano-banana-pro".
auto_generatebooleanEnable cron-based auto post generation.
yolo_modebooleanAuto-publish generated content to selected platforms.
yolo_platformsstring[]Platforms to auto-publish to when yolo_mode is true.
generate_carouselsbooleanGenerate carousel posts during auto-gen.
generate_videosbooleanGenerate video posts during auto-gen.
website_urlstringBrand website, used for tone/context scraping.
languagestringOutput language (e.g. "en", "es").
curl -X PUT https://www.postquick.ai/api/v1/content-groups/uuid-abc-123/instructions \
-H "Authorization: Bearer pq_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"brand_name": "Acme Fitness",
"target_audience": "Busy professionals, 25-40",
"tone": "Motivating, direct, no-nonsense",
"topics": "Home workouts, nutrition, mindset",
"instructions": "Always end with a clear CTA. Avoid fitness jargon.",
"include_image": true,
"image_model": "nano-banana-pro"
}'{
"success": true,
"data": {
"instructions": {
"app_id": "uuid-abc-123",
"brand_name": "Acme Fitness",
"tone": "Motivating, direct, no-nonsense",
...
"updated_at": "2026-04-17T09:31:02Z"
}
}
}Group analytics
/v1/content-groups/:id/analyticsReturns aggregate social performance analytics for all posts in a content group: totals (views, likes, comments, shares, saves), per-platform breakdown, per-content-type breakdown, top 10 posts by views, and a daily trend.
Metrics are refreshed by the background analytics cron every 4 hours. lastFetched in each platform row tells you when that value was captured.
Parameters
periodstringTime window: "7d", "30d" (default), or "90d".
curl "https://www.postquick.ai/api/v1/content-groups/uuid-abc-123/analytics?period=30d" \ -H "Authorization: Bearer pq_live_your_key_here"
{
"success": true,
"data": {
"groupId": "uuid-abc-123",
"groupName": "Acme Fitness",
"period": "30d",
"totals": {
"views": 145230,
"likes": 8912,
"comments": 423,
"shares": 1104,
"saves": 678,
"engagementRate": 0.0720
},
"platformBreakdown": [
{ "platform": "instagram", "totalViews": 89210, "totalLikes": 5612, "postCount": 18, "avgEngagementRate": 0.083 },
{ "platform": "twitter_x", "totalViews": 56020, "totalLikes": 3300, "postCount": 22, "avgEngagementRate": 0.061 }
],
"contentTypeBreakdown": [
{ "postType": "carousel", "postCount": 12, "totalViews": 72100, "avgEngagementRate": 0.092 },
{ "postType": "video", "postCount": 5, "totalViews": 41230, "avgEngagementRate": 0.071 }
],
"topPosts": [
{ "postId": "post-1", "postType": "carousel", "totalViews": 15420, "engagementRate": 0.11, "platforms": ["instagram"] }
],
"dailyTrend": [
{ "date": "2026-03-20", "views": 4821, "likes": 312, "comments": 14, "shares": 42 }
],
"totalPostsWithAnalytics": 40
}
}Generate a post
/v1/posts/generateUses AI to generate a complete social media post based on your content group's brand instructions, tone, target audience, and content strategy. The AI analyzes your brand profile and creates on-brand content automatically.
Optionally generates an accompanying image (consumes 1 image credit). The post is created with status "pending" and can be edited before publishing.
Consumes: 1 text generation credit (+ 1 image credit if generateImage: true).
Parameters
contentGroupIdstringrequiredThe content group to generate for. The group's brand profile, tone, and instructions shape the AI output.
generateImagebooleanWhether to also generate an AI image for the post. Defaults to false. Consumes an additional image generation credit.
curl -X POST https://www.postquick.ai/api/v1/posts/generate \
-H "Authorization: Bearer pq_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"contentGroupId": "uuid-abc-123",
"generateImage": true
}'{
"success": true,
"data": {
"post": {
"id": "post-xyz-789",
"app_id": "uuid-abc-123",
"content": "Just shipped our new AI dashboard ✨\n\nThree months of late nights, 47 cups of coffee, and one very patient designer later — it's live.\n\nThe best tools don't just work. They disappear.\n\n#buildinpublic #saas #ai",
"status": "pending",
"post_type": "image",
"image_url": "https://storage.postquick.ai/post-images/user-123/gemini-flash-abc.png",
"image_urls": null,
"video_url": null,
"platforms": ["instagram", "twitter"],
"posted_platforms": [],
"is_manual": false,
"scheduled_for": null,
"error_message": null,
"created_at": "2026-03-25T14:30:00Z",
"updated_at": null,
"posted_at": null
}
}
}Create a post
/v1/posts/createManually create a post with your own content. Supports text, single image, carousel (2-10 images), and video post types. Does not consume generation credits.
Media URLs must be publicly accessible. The API does not upload files — host your media on your own CDN or use the /images/generate endpoint to create AI images.
Parameters
contentGroupIdstringrequiredThe content group this post belongs to.
contentstringrequiredThe post text/caption. Can include hashtags and emojis.
postTypestringrequiredOne of: "text", "image", "carousel", "video". Determines which media fields are required.
platformsstring[]Target platforms for publishing. Defaults to the content group's configured platforms.
imageUrlstringPublic URL of the image (required for postType: "image").
imageUrlsstring[]Array of 2-10 public image URLs (required for postType: "carousel").
videoUrlstringPublic URL of the video (required for postType: "video").
isDraftbooleanSave as draft (status: "draft") instead of pending. Default: false.
scheduledForstringISO 8601 timestamp for scheduled publishing. Must be in the future.
linkedinTargetobjectLinkedIn target: { type: "personal" | "organization", organizationId?: string }. Required when publishing to LinkedIn.
facebookTargetobjectFacebook page target: { pageId: string, pageName?: string }. Required when publishing to Facebook.
threadPartsobject[]Array of thread parts for reply-based threads. Supported on Twitter/X, Threads, and Bluesky — each part is posted as a reply to the previous. Format: [{ text, image_urls?, video_url?, post_type }]. The root content field should match the first part. Minimum 2 parts.
curl -X POST https://www.postquick.ai/api/v1/posts/create \
-H "Authorization: Bearer pq_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"contentGroupId": "uuid-abc-123",
"content": "Excited to announce our Series A! 🚀\n\n$10M led by @ventureCapital to scale our platform.\n\nThank you to everyone who believed in us.\n\n#startup #funding",
"postType": "image",
"platforms": ["instagram", "twitter", "linkedin"],
"imageUrl": "https://example.com/announcement.jpg"
}'{
"success": true,
"data": {
"post": {
"id": "post-manual-456",
"app_id": "uuid-abc-123",
"content": "Excited to announce our Series A! 🚀...",
"status": "pending",
"post_type": "image",
"image_url": "https://example.com/announcement.jpg",
"platforms": ["instagram", "twitter", "linkedin"],
"posted_platforms": [],
"is_manual": true,
"created_at": "2026-03-25T14:45:00Z"
}
}
}Creating a reply thread
Pass threadParts to create a multi-part thread. Each part is posted as a reply to the previous one on twitter_x, threads, and bluesky. Other platforms will only post the first part.
{
"contentGroupId": "uuid-abc-123",
"content": "The 3 biggest mistakes new founders make (a thread) 🧵",
"postType": "text",
"platforms": ["twitter_x", "threads", "bluesky"],
"threadParts": [
{ "text": "The 3 biggest mistakes new founders make (a thread) 🧵", "post_type": "text" },
{ "text": "1/ Hiring too fast. Team size is a lagging indicator of success, not a leading one.", "post_type": "text" },
{ "text": "2/ Building in secret. Customers can't validate what they can't see.", "post_type": "text" },
{ "text": "3/ Ignoring retention. Growth without retention is a leaky bucket.", "post_type": "text" }
]
}List posts
/v1/posts?contentGroupId=...&status=...Returns all posts for a content group, optionally filtered by status. Results are sorted by created_at descending (newest first). Use this to build content calendars, dashboards, or monitoring tools.
Status filtering is useful for building queues: pending for drafts awaiting publish, scheduled for upcoming posts, posted for published content.
Query Parameters
contentGroupIdstringrequiredFilter by content group. Returns 400 if missing.
statusstringFilter by status: "pending", "draft", "posted", "scheduled", "failed", "processing", "published".
curl "https://www.postquick.ai/api/v1/posts?contentGroupId=uuid-abc-123&status=pending" \ -H "Authorization: Bearer pq_live_your_key_here"
{
"success": true,
"data": {
"posts": [
{
"id": "post-1",
"content": "Post content here...",
"status": "pending",
"post_type": "image",
"image_url": "https://...",
"platforms": ["instagram"],
"created_at": "2026-03-25T14:30:00Z"
},
{
"id": "post-2",
"content": "Another post...",
"status": "pending",
"post_type": "text",
"platforms": ["twitter"],
"created_at": "2026-03-25T12:00:00Z"
}
]
}
}Retrieve a post
/v1/posts/:idRetrieves a single post by ID with the complete object schema. Returns 404 if the post doesn't exist or you don't have access to it.
Use this to check publish status, fetch the latest version before editing, or retrieve media URLs.
curl https://www.postquick.ai/api/v1/posts/post-xyz-789 \ -H "Authorization: Bearer pq_live_your_key_here"
{
"success": true,
"data": {
"post": {
"id": "post-xyz-789",
"app_id": "uuid-abc-123",
"content": "Just shipped our new AI dashboard ✨...",
"status": "posted",
"post_type": "image",
"image_url": "https://storage.postquick.ai/...",
"platforms": ["instagram", "twitter"],
"posted_platforms": ["instagram", "twitter"],
"created_at": "2026-03-25T14:30:00Z",
"posted_at": "2026-03-25T15:00:00Z"
}
}
}Update a post
/v1/posts/:idUpdate a post's content, platforms, media URLs, or scheduling. Only provided fields are updated (partial update). Cannot update posts that have already been published (status "posted" or "published").
Returns 404 if the post doesn't exist, 409 if the post is already published or processing.
Parameters
contentstringUpdated post text/caption.
platformsstring[]Updated target platforms.
imageUrlstringUpdated image URL (for image posts).
imageUrlsstring[]Updated image URLs (for carousel posts).
scheduledForstringUpdated scheduled time (ISO 8601).
threadPartsobject[]Replace the reply-thread structure. Pass an empty array to convert back to a single post. Format: [{ text, image_urls?, video_url?, post_type }].
curl -X PUT https://www.postquick.ai/api/v1/posts/post-xyz-789 \
-H "Authorization: Bearer pq_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"content": "Updated caption with new CTA ✨\n\nClick link in bio!",
"platforms": ["instagram", "twitter", "threads"]
}'{
"success": true,
"data": {
"post": {
"id": "post-xyz-789",
"content": "Updated caption with new CTA ✨\n\nClick link in bio!",
"platforms": ["instagram", "twitter", "threads"],
"updated_at": "2026-03-25T15:30:00Z",
...
}
}
}Delete a post
/v1/posts/:idPermanently deletes a post. This cannot be undone. Deleting a post does not un-publish it from platforms — it only removes it from your PostQuickAI account.
Returns 404 if the post doesn't exist or you don't have permission to delete it.
curl -X DELETE https://www.postquick.ai/api/v1/posts/post-xyz-789 \ -H "Authorization: Bearer pq_live_your_key_here"
{
"success": true,
"data": {
"message": "Post deleted successfully"
}
}Publish a post
/v1/posts/:id/publishPublishes a post to the specified platforms immediately. Requires connected social accounts on the content group and returns the publish result, including successful platforms and any platform-specific errors.
Returns 403 if you don't have connected accounts for the target platforms.
Platform-specific requirements:
- LinkedIn: requires
linkedinTarget - Facebook: requires
facebookTarget - TikTok: image posts require min 2 images, text-only not supported
- Instagram: requires business/creator account
Parameters
platformsstring[]requiredPlatforms to publish to. Must have connected accounts for each.
linkedinTargetobjectLinkedIn target: { type: "personal" | "organization", organizationId?: string }.
facebookTargetobjectFacebook page target: { pageId: string, pageName?: string }.
curl -X POST https://www.postquick.ai/api/v1/posts/post-xyz-789/publish \
-H "Authorization: Bearer pq_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"platforms": ["instagram", "twitter"]
}'{
"success": true,
"data": {
"post": {
"id": "post-xyz-789",
"status": "posted",
"posted_platforms": ["instagram", "twitter"],
"posted_at": "2026-03-25T15:00:00Z",
...
},
"publishedTo": ["instagram", "twitter"],
"errors": []
}
}Partial Failure Handling
If publishing fails on some platforms but succeeds on others, the post status remains "posted", posted_platforms contains successful platforms, and errors array contains failure details.
Schedule a post
/v1/posts/:id/scheduleSchedules a post for future publishing. The cron system automatically publishes it at the specified time (runs every 15 minutes). Post status changes to "scheduled".
The scheduled time must be at least 5 minutes in the future. Returns 400 if scheduledFor is in the past or too soon.
To cancel a scheduled post, update its status to "draft" via PUT /v1/posts/:id or delete it.
Parameters
contentGroupIdstringrequiredThe content group the post belongs to.
scheduledForstringrequiredISO 8601 timestamp. Must be at least 5 minutes in the future.
platformsstring[]Override the post's target platforms. If omitted, uses post.platforms.
curl -X POST https://www.postquick.ai/api/v1/posts/post-xyz-789/schedule \
-H "Authorization: Bearer pq_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"contentGroupId": "uuid-abc-123",
"scheduledFor": "2026-04-01T10:00:00Z",
"platforms": ["instagram", "twitter"]
}'{
"success": true,
"data": {
"post": {
"id": "post-xyz-789",
"status": "scheduled",
"scheduled_for": "2026-04-01T10:00:00Z",
"platforms": ["instagram", "twitter"],
...
}
}
}Regenerate a post
/v1/posts/:id/regenerateRewrites an existing post's content using AI based on natural-language feedback. Optionally also regenerates the attached image.
Counts as 1 AI text request. If generateImage: true, also counts as 1 image generation against your monthly image limit.
Parameters
instructionsstringrequiredFeedback guiding the rewrite (e.g. "make it shorter and less salesy").
generateImagebooleanIf true, also regenerate the image. Default: false.
imageModelstring"gemini-flash" | "gpt-image-1.5" | "nano-banana-pro". Default: "gemini-flash".
curl -X POST https://www.postquick.ai/api/v1/posts/post-xyz-789/regenerate \
-H "Authorization: Bearer pq_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"instructions": "Make it shorter, more punchy, and add a clear CTA.",
"generateImage": false
}'{
"success": true,
"data": {
"post": {
"id": "post-xyz-789",
"content": "(rewritten text)",
"image_url": "...",
"updated_at": "2026-04-17T09:42:00Z",
...
}
}
}Update post images
/v1/posts/:id/imagesAttach, replace, or remove images on a post. Useful for swapping in a custom image after generation or preparing a post for re-publish.
Parameters
actionstringrequired"set_single_image", "set_multiple_images", "remove_all_images", or "remove_single_image".
imageUrlstringRequired when action is "set_single_image". Must be a publicly accessible URL.
imageUrlsstring[]Required when action is "set_multiple_images". Carousel slides, in order.
curl -X PUT https://www.postquick.ai/api/v1/posts/post-xyz-789/images \
-H "Authorization: Bearer pq_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"action": "set_multiple_images",
"imageUrls": [
"https://cdn.example.com/slide1.jpg",
"https://cdn.example.com/slide2.jpg"
]
}'{
"success": true,
"data": {
"post": {
"id": "post-xyz-789",
"image_url": null,
"image_urls": ["https://cdn.example.com/slide1.jpg", "https://cdn.example.com/slide2.jpg"],
...
}
}
}Reset posted platforms
/v1/posts/:id/reset-platformsClears the posted_platforms array and error_message on a post. Use after fixing a failed publish so POST /v1/posts/:id/publish will retry every platform cleanly.
curl -X POST https://www.postquick.ai/api/v1/posts/post-xyz-789/reset-platforms \ -H "Authorization: Bearer pq_live_your_key_here"
{
"success": true,
"data": {
"post": {
"id": "post-xyz-789",
"posted_platforms": [],
"error_message": null,
...
}
}
}Post analytics
/v1/posts/:id/analyticsReturns per-platform social performance metrics (views, likes, comments, shares, saves) for a single post, plus a 30-day history. Metrics are refreshed every 4 hours by the background analytics cron.
For video posts, pass ?type=video.
Parameters
typestring"post" (default) or "video". Determines which table the ID refers to.
curl https://www.postquick.ai/api/v1/posts/post-xyz-789/analytics \ -H "Authorization: Bearer pq_live_your_key_here"
{
"success": true,
"data": {
"postId": "post-xyz-789",
"postType": "post",
"totals": {
"views": 15420,
"likes": 892,
"comments": 41,
"shares": 104,
"saves": 23,
"engagementRate": 0.067
},
"platforms": [
{ "platform": "instagram", "views": 12100, "likes": 780, "comments": 35, "shares": 82, "fetched_at": "2026-04-17T08:00:00Z" },
{ "platform": "twitter_x", "views": 3320, "likes": 112, "comments": 6, "shares": 22, "fetched_at": "2026-04-17T08:00:00Z" }
],
"history": [
{ "snapshot_date": "2026-04-15", "views": 8210, "likes": 512, "comments": 22 }
],
"lastFetched": "2026-04-17T08:00:00Z"
}
}Generate a caption
/v1/captions/generateGenerates a social media caption using AI, grounded in your content group's brand profile (tone, target audience, unique angle). Uses GPT-4.1 or Claude 3.7 based on your plan. Subject to monthly AI text generation limits (400/month for Basic, 2,000/month for Pro).
Returns 403 if you've exceeded your monthly AI text usage limit. This limit is shared across dashboard and API usage.
If you provide a content group ID, the AI personalizes the caption using the group's content instructions. Without a content group, the AI generates generic captions.
Parameters
topicstringrequiredThe topic or theme for the caption (e.g., "Product launch announcement", "Weekend motivation").
contentGroupIdstringContent group ID to ground the caption in brand voice. Highly recommended for brand-consistent content.
platformstringTarget platform (instagram, twitter, linkedin, etc.). Optimizes caption length and style for that platform.
lengthstringDesired length: "short" (1-2 sentences), "medium" (2-4 sentences), "long" (5+ sentences). Default: "medium".
curl -X POST https://www.postquick.ai/api/v1/captions/generate \
-H "Authorization: Bearer pq_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"topic": "New AI feature launch",
"contentGroupId": "uuid-abc-123",
"platform": "instagram",
"length": "medium"
}'{
"success": true,
"data": {
"caption": "🚀 We just launched our most powerful AI feature yet — automated content scheduling that learns YOUR brand voice.\n\nNo more generic posts. No more copy-paste templates. Just authentic content that sounds like you.\n\nTry it free for 14 days. Link in bio. 👆\n\n#AIMarketing #ContentCreation #SocialMediaAutomation"
}
}Usage Limits
Each caption generation counts as 1 AI text request against your monthly limit. Check your remaining usage with GET /v1/usage. Exceeding the limit returns 403.
Generate carousel caption
/v1/captions/carouselGenerates a caption optimized for carousel posts (Instagram/TikTok multi-image posts). The AI accounts for carousel-specific best practices: teasing the swipe, referencing multiple images, encouraging engagement.
Same usage limits and brand grounding as standard caption generation.
Parameters
topicstringrequiredThe carousel theme (e.g., "5 tips for better sleep", "Product collection showcase").
contentGroupIdstringContent group ID for brand voice grounding.
platformstringTarget platform. Default: "instagram".
slideCountnumberNumber of images in the carousel. Helps AI reference "swipe through all X slides".
curl -X POST https://www.postquick.ai/api/v1/captions/carousel \
-H "Authorization: Bearer pq_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"topic": "5 productivity hacks for founders",
"contentGroupId": "uuid-abc-123",
"slideCount": 5
}'{
"success": true,
"data": {
"caption": "5 productivity hacks every founder needs 👇\n\nSwipe through to see the exact systems we use to ship faster without burning out.\n\n(Slide 3 is the game-changer 🔥)\n\nSave this for later → you'll need it.\n\n#FounderLife #ProductivityHacks #StartupTips"
}
}Generate video caption
/v1/captions/videoGenerates a caption optimized for video posts (Reels, TikToks, YouTube Shorts, LinkedIn videos). The AI uses video-specific hooks, calls-to-action, and engagement patterns.
For AI-generated videos, you can pass the video description/prompt to help the AI create a contextual caption. For user-uploaded videos, describe the video content in the topic field.
Parameters
topicstringrequiredVideo topic or the original video generation prompt.
contentGroupIdstringContent group ID for brand voice.
platformstringTarget platform (instagram, tiktok, youtube, linkedin). Default: "instagram".
durationnumberVideo duration in seconds. Helps AI reference "watch till the end" for longer videos.
curl -X POST https://www.postquick.ai/api/v1/captions/video \
-H "Authorization: Bearer pq_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"topic": "Behind the scenes of our product design process",
"contentGroupId": "uuid-abc-123",
"platform": "instagram",
"duration": 30
}'{
"success": true,
"data": {
"caption": "POV: You're watching our actual design process 🎨\n\n30 seconds from idea → prototype → final product.\n\nThis is how we ship fast without sacrificing quality.\n\nDrop a 🔥 if you want the full breakdown.\n\n#ProductDesign #BehindTheScenes #StartupLife"
}
}Adjust tone
/v1/content/adjust-toneRewrites existing content in a different tone while preserving the core message. Supports 10+ tones: professional, casual, friendly, enthusiastic, formal, humorous, inspirational, educational, storytelling, urgent.
Grounded in your content group's brand profile if provided. Counts as 1 AI text request against your monthly limit.
Use this to quickly A/B test different tones for the same post, or adapt content for different platforms (e.g., professional for LinkedIn, casual for Instagram).
Parameters
contentstringrequiredThe original text to rewrite.
targetTonestringrequiredDesired tone: "professional", "casual", "friendly", "enthusiastic", "formal", "humorous", "inspirational", "educational", "storytelling", "urgent".
contentGroupIdstringContent group ID to ground the rewrite in brand voice. Ensures the new tone still sounds like your brand.
curl -X POST https://www.postquick.ai/api/v1/content/adjust-tone \
-H "Authorization: Bearer pq_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"content": "We launched a new feature. Check it out.",
"targetTone": "enthusiastic",
"contentGroupId": "uuid-abc-123"
}'{
"success": true,
"data": {
"adjustedContent": "🎉 We just dropped our most exciting feature yet! This is HUGE — you're gonna love it. Go check it out right now! 🚀",
"originalTone": "neutral",
"newTone": "enthusiastic"
}
}Tone Reference
- Professional: Corporate, polished, authoritative
- Casual: Relaxed, conversational, approachable
- Friendly: Warm, welcoming, personal
- Enthusiastic: Energetic, excited, positive
- Formal: Official, respectful, traditional
- Humorous: Funny, witty, entertaining
- Inspirational: Motivating, uplifting, empowering
- Educational: Informative, clear, teaching-focused
- Storytelling: Narrative, engaging, descriptive
- Urgent: Time-sensitive, action-oriented, pressing
Proofread
/v1/content/proofreadProofreads content for grammar, spelling, punctuation, and clarity issues. Returns the corrected text plus a detailed list of changes with explanations.
Preserves tone and style — only fixes errors, doesn't rewrite. Counts as 1 AI text request.
Useful for quality control before publishing, especially for user-generated content or quick drafts.
Parameters
contentstringrequiredThe text to proofread.
contentGroupIdstringContent group ID. Optional but helps AI understand brand-specific terminology.
curl -X POST https://www.postquick.ai/api/v1/content/proofread \
-H "Authorization: Bearer pq_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"content": "Were launching are new feature tommorow. Its going to be amazing, you should definitly check it out!"
}'{
"success": true,
"data": {
"correctedContent": "We're launching our new feature tomorrow. It's going to be amazing, you should definitely check it out!",
"corrections": [
{
"type": "spelling",
"original": "Were",
"corrected": "We're",
"explanation": "Missing apostrophe in contraction"
},
{
"type": "grammar",
"original": "are",
"corrected": "our",
"explanation": "Wrong word - 'our' is possessive, 'are' is verb"
},
{
"type": "spelling",
"original": "tommorow",
"corrected": "tomorrow",
"explanation": "Misspelled word"
},
{
"type": "spelling",
"original": "definitly",
"corrected": "definitely",
"explanation": "Common misspelling"
}
],
"hasErrors": true
}
}Make concise
/v1/content/make-conciseShortens content while preserving the core message and key details. Removes filler words, redundancies, and unnecessary clauses. Useful for fitting content within platform character limits (Twitter 280 chars) or improving readability.
You can specify a target character or word count. The AI will aim for that length while keeping the essential meaning.
Counts as 1 AI text request against your monthly limit.
Parameters
contentstringrequiredThe text to shorten.
contentGroupIdstringContent group ID for brand voice preservation.
targetLengthnumberTarget character count (e.g., 280 for Twitter). AI will aim for this length.
preserveTonebooleanIf true, maintains original tone. If false, optimizes for brevity even if tone shifts slightly. Default: true.
curl -X POST https://www.postquick.ai/api/v1/content/make-concise \
-H "Authorization: Bearer pq_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"content": "I wanted to take a moment to share with you all that we have just launched our brand new feature that we have been working on for several months now. It is something that I think you are all really going to love and appreciate, and I would highly encourage everyone to go ahead and check it out when you get a chance.",
"targetLength": 280
}'{
"success": true,
"data": {
"conciseContent": "Just launched our new feature after months of work. We think you'll love it — check it out!",
"originalLength": 285,
"newLength": 94,
"reduction": "67%"
}
}Custom edit
/v1/content/custom-editApplies a custom editing instruction to content. Pass free-form natural language instructions like "add more emojis", "remove the sales pitch", "make it sound more technical", "add a call-to-action at the end".
This is the most flexible content editing endpoint — use it when the other specialized endpoints (tone, proofread, concise) don't match your exact need.
Grounded in content group brand profile if provided. Counts as 1 AI text request.
Parameters
contentstringrequiredThe original text to edit.
instructionstringrequiredNatural language editing instruction (e.g., "add more emojis and make it fun", "remove technical jargon").
contentGroupIdstringContent group ID for brand voice grounding.
curl -X POST https://www.postquick.ai/api/v1/content/custom-edit \
-H "Authorization: Bearer pq_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"content": "We launched a new feature. It helps you schedule posts.",
"instruction": "Add emojis and a strong call-to-action at the end",
"contentGroupId": "uuid-abc-123"
}'{
"success": true,
"data": {
"editedContent": "🚀 We just launched a game-changing new feature! It helps you schedule posts effortlessly.\n\nTry it now and never miss a posting window again! 👉",
"instruction": "Add emojis and a strong call-to-action at the end"
}
}Example Instructions
- "Make it shorter and punchier"
- "Add 3 relevant emojis"
- "Remove the first sentence"
- "Add a question at the end to boost engagement"
- "Replace technical terms with simple language"
- "Add line breaks for better readability"
- "Make it sound more confident and assertive"
Generate an image
/v1/images/generateGenerates an AI image using one of 3 models: Gemini Flash (default, fast, good quality), GPT Image 1.5 (high quality), or Nano Banana Pro (premium photorealistic/stylized).
Subject to monthly image generation limits: 100/month for Basic, 500/month for Pro. This limit is shared across dashboard and API usage. Returns 403 if limit exceeded.
Generated images are automatically stored in your PostQuickAI account and accessible via the dashboard Files page. The response includes a direct URL to the image (hosted on Supabase Storage).
Recommended aspect ratios by platform:
- Instagram feed: 1:1 (square) or 4:5 (portrait)
- Instagram Stories/Reels: 9:16 (vertical)
- Twitter: 16:9 (landscape) or 1:1
- LinkedIn: 1.91:1 or 1:1
- TikTok: 9:16 (vertical)
Parameters
promptstringrequiredDetailed image generation prompt. Be specific: describe subject, style, lighting, composition, mood.
modelstringImage model: "gemini-flash" (default), "gpt-image-1.5", "nano-banana-pro". See Image Models reference.
aspectRatiostringAspect ratio: "1:1", "4:5", "9:16", "16:9", "3:4", "4:3". Default: "1:1".
contentGroupIdstringContent group ID. If provided, the prompt is grounded in the group's brand profile for consistent visual style.
curl -X POST https://www.postquick.ai/api/v1/images/generate \
-H "Authorization: Bearer pq_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"prompt": "A modern minimalist office workspace with a laptop, coffee cup, and plants. Natural lighting, warm tones, clean aesthetic. Professional but cozy.",
"model": "gemini-flash",
"aspectRatio": "4:5",
"contentGroupId": "uuid-abc-123"
}'{
"success": true,
"data": {
"imageUrl": "https://your-project.supabase.co/storage/v1/object/public/post-images/user-uuid/1711234567890-image.png",
"model": "gemini-flash",
"aspectRatio": "4:5",
"width": 1080,
"height": 1350,
"prompt": "A modern minimalist office workspace with a laptop, coffee cup, and plants. Natural lighting, warm tones, clean aesthetic. Professional but cozy."
}
}Model Comparison
- Gemini Flash: Best for most use cases. Fast (3-8s), good quality, reliable. Default choice.
- GPT Image 1.5: Higher quality, better at complex prompts and text rendering. Slightly slower (8-15s).
- Nano Banana Pro: Premium photorealistic or stylized. Best for product photos, portraits, creative content (5-10s).
Generate a video
/v1/videos/generateGenerates an AI video using Google Veo or OpenAI Sora models. This is an async operation: the endpoint returns 202 Accepted immediately with a video ID, then the video generates in the background (2-10 minutes depending on model and duration).
Workflow: POST to generate → poll GET /v1/videos/:id/status every 10-30 seconds until status is "completed" → retrieve video with GET /v1/videos/:id.
Video generation costs video credits (not monthly usage limits). Veo Fast and Sora 2 cost 1 credit each. Veo 3.1 and Sora 2 Pro cost 3 credits each. Users get 100 credits/month (Basic) or 500 credits/month (Pro). Check remaining credits with GET /v1/usage.
Returns 403 if you don't have enough video credits. Returns 400 if prompt is invalid or parameters are out of range.
Parameters
promptstringrequiredDetailed video generation prompt. Describe the scene, action, camera movement, style. Max 500 characters.
modelstringVideo model: "veo-3.1-fast-generate-preview" (1 credit, default), "veo-3.1-generate-preview" (3 credits), "sora-2" (1 credit), "sora-2-pro" (3 credits). See Video Models reference.
durationnumberVideo duration in seconds. Veo: 4, 6, or 8. Sora: 4, 8, or 12. Default: 6.
aspectRatiostringAspect ratio: "9:16" (portrait, TikTok/Reels) or "16:9" (landscape, YouTube). Default: "9:16".
contentGroupIdstringContent group ID. Grounds the video style in your brand profile.
curl -X POST https://www.postquick.ai/api/v1/videos/generate \
-H "Authorization: Bearer pq_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"prompt": "A close-up of coffee being poured into a white ceramic mug on a wooden table. Morning sunlight streaming through a window. Slow motion, cinematic, warm tones.",
"model": "veo-3.1-fast-generate-preview",
"duration": 6,
"aspectRatio": "9:16",
"contentGroupId": "uuid-abc-123"
}'{
"success": true,
"data": {
"video": {
"id": "video-uuid-xyz-789",
"title": "Coffee pouring cinematic",
"description": "A close-up of coffee being poured into a white ceramic mug on a wooden table. Morning sunlight streaming through a window. Slow motion, cinematic, warm tones.",
"status": "generating",
"model": "veo-3.1-fast-generate-preview",
"duration": 6,
"aspectRatio": "9:16",
"creditsUsed": 1,
"created_at": "2026-03-25T16:00:00Z",
"video_url": null
},
"estimatedCompletionTime": "2-5 minutes"
}
}Polling Best Practices
Poll GET /v1/videos/:id/status every 15-30 seconds. Don't poll more frequently — video generation takes 2-10 minutes regardless.
Faster models (Veo Fast, Sora 2): ~2-4 min. Slower models (Veo 3.1, Sora Pro): ~5-10 min. If status is "failed", credits are auto-refunded.
Retrieve a video
/v1/videos/:idRetrieves full details for a video by ID, including video URL (when completed), status, metadata, and publishing history.
Returns 404 if the video doesn't exist or you don't have access to it.
The video_url field is null until status is "completed". Use GET /v1/videos/:id/status for lightweight polling.
curl https://www.postquick.ai/api/v1/videos/video-uuid-xyz-789 \ -H "Authorization: Bearer pq_live_your_key_here"
{
"success": true,
"data": {
"video": {
"id": "video-uuid-xyz-789",
"app_id": "uuid-abc-123",
"user_id": "user-uuid-123",
"title": "Coffee pouring cinematic",
"description": "A close-up of coffee being poured into a white ceramic mug...",
"status": "completed",
"video_url": "https://your-project.supabase.co/storage/v1/object/public/videos/user-uuid/video-xyz.mp4",
"optimized_video_url": "https://your-project.supabase.co/storage/v1/object/public/videos/user-uuid/video-xyz-optimized.mp4",
"duration": 6,
"platforms": ["instagram", "tiktok"],
"posted_platforms": [],
"scheduled_for": null,
"error_message": null,
"created_at": "2026-03-25T16:00:00Z",
"updated_at": "2026-03-25T16:04:32Z"
}
}
}Check video status
/v1/videos/:id/statusLightweight endpoint for polling video generation progress. Returns only status, video_url, and error_message (if any).
Use this instead of GET /v1/videos/:id when polling for completion to reduce response size and latency.
Status values:
"generating"— video is being created (poll every 15-30s)"completed"— video ready,video_urlavailable"failed"— generation failed, credits refunded, seeerror_message"processing"— video is being published (after calling publish endpoint)"posted"— successfully published to platforms
curl https://www.postquick.ai/api/v1/videos/video-uuid-xyz-789/status \ -H "Authorization: Bearer pq_live_your_key_here"
{
"success": true,
"data": {
"status": "completed",
"video_url": "https://your-project.supabase.co/storage/v1/object/public/videos/user-uuid/video-xyz.mp4",
"error_message": null
}
}Delete a video
/v1/videos/:idDeletes a video and its associated files from storage. Video credits are NOT refunded when deleting completed videos (only refunded automatically if generation fails).
You can delete videos in any status: generating, completed, failed, posted. If the video is currently generating, the generation process is cancelled.
Returns 404 if the video doesn't exist or you don't have access to it.
curl -X DELETE https://www.postquick.ai/api/v1/videos/video-uuid-xyz-789 \ -H "Authorization: Bearer pq_live_your_key_here"
{
"success": true,
"data": {
"message": "Video deleted successfully"
}
}Publish a video
/v1/videos/:id/publishThis is an async operation. Returns 202 Accepted immediately and dispatches the video to our Cloud Run publishing service. The actual publish happens in the background (5-60 seconds depending on video preprocessing needs).
Video must be in "completed" status. Returns 400 if video is still generating or already published. Returns 409 if video is currently processing.
Check publish progress by polling GET /v1/videos/:id/status — status will change from "completed" → "processing" → "posted".
Requires connected social accounts on the content group. Returns 403 if you don't have accounts connected for the target platforms.
Parameters
contentGroupIdstringrequiredThe content group the video belongs to. Used to fetch connected social accounts.
platformsstring[]requiredPlatforms to publish to. Must have connected accounts for each.
captionstringVideo caption/description. If omitted, uses the video's original generation prompt as the caption.
linkedinTargetobjectLinkedIn target: { type: "personal" | "organization", organizationId?: string }.
facebookTargetobjectFacebook page target: { pageId: string, pageName?: string }.
curl -X POST https://www.postquick.ai/api/v1/videos/video-uuid-xyz-789/publish \
-H "Authorization: Bearer pq_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"contentGroupId": "uuid-abc-123",
"platforms": ["instagram", "tiktok"],
"caption": "Morning coffee vibes ☕️✨ #CoffeeLovers #MorningRoutine"
}'{
"success": true,
"data": {
"message": "Video publishing initiated. Check status at GET /v1/videos/:id/status",
"video": {
"id": "video-uuid-xyz-789",
"status": "processing",
...
}
}
}Schedule a video
/v1/videos/:id/scheduleSchedules a video for future publishing. The cron system automatically publishes it at the specified time (runs every 15 minutes). Video status changes to "scheduled".
Video must be in "completed" status. The scheduled time must be at least 5 minutes in the future. Returns 400 if scheduledFor is in the past or video is not completed.
To cancel a scheduled video, update it back to "completed" status or delete it.
Parameters
scheduledForstringrequiredISO 8601 timestamp. Must be at least 5 minutes in the future.
platformsstring[]requiredPlatforms to publish to when the scheduled time arrives.
captionstringVideo caption to use when publishing.
curl -X POST https://www.postquick.ai/api/v1/videos/video-uuid-xyz-789/schedule \
-H "Authorization: Bearer pq_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"scheduledFor": "2026-04-01T14:00:00Z",
"platforms": ["instagram", "tiktok"],
"caption": "Happy Monday! ☕️"
}'{
"success": true,
"data": {
"video": {
"id": "video-uuid-xyz-789",
"status": "scheduled",
"scheduled_for": "2026-04-01T14:00:00Z",
"platforms": ["instagram", "tiktok"],
...
}
}
}Reset video posted platforms
/v1/videos/:id/reset-platformsClears posted_platforms, error_message, and per-platform error state on a video so it can be republished cleanly.
curl -X POST https://www.postquick.ai/api/v1/videos/video-abc-456/reset-platforms \ -H "Authorization: Bearer pq_live_your_key_here"
{
"success": true,
"data": {
"video": {
"id": "video-abc-456",
"posted_platforms": [],
"error_message": null,
...
}
}
}List connected accounts
/v1/accountsReturns all social media accounts connected to your PostQuickAI user account, grouped by platform. Includes account metadata like username, profile picture, account type (personal/business), and connection status.
Social accounts must be connected via OAuth in the dashboard — the API cannot connect new accounts, only read existing connections.
Use this endpoint to verify which platforms you can publish to before calling publish/schedule endpoints.
curl https://www.postquick.ai/api/v1/accounts \ -H "Authorization: Bearer pq_live_your_key_here"
{
"success": true,
"data": {
"accounts": [
{
"id": "acc-uuid-123",
"platform": "instagram",
"account_name": "@mybrand",
"account_type": "business",
"profile_picture_url": "https://...",
"is_active": true,
"connected_at": "2026-01-15T10:30:00Z"
},
{
"id": "acc-uuid-456",
"platform": "twitter",
"account_name": "@mybrand",
"account_type": "personal",
"is_active": true,
"connected_at": "2026-01-20T14:00:00Z"
},
{
"id": "acc-uuid-789",
"platform": "linkedin",
"account_name": "John Doe",
"account_type": "personal",
"is_active": true,
"connected_at": "2026-02-01T09:00:00Z"
}
],
"total": 3
}
}Disconnect a social account
/v1/accounts/:idPermanently disconnect a social account from its content group. This deletes the OAuth tokens stored by PostQuickAI and prevents future publishing to this account until it is reconnected through the dashboard.
Existing posts that were already published to the platform are not affected. Scheduled posts targeting that platform will fail with a credentials error unless re-connected. To initiate a new OAuth connection, use the dashboard — the full OAuth redirect flow is not currently exposed via API.
curl -X DELETE https://www.postquick.ai/api/v1/accounts/account-uuid-456 \ -H "Authorization: Bearer pq_live_your_key_here"
{
"success": true,
"data": {
"deleted": true
}
}Get usage statistics
/v1/usageReturns your current usage across all PostQuickAI limits and quotas. Includes monthly AI text generation usage, image generation usage, video credits, content group count, and rate limit status.
All limits are shared between dashboard and API usage. Use this endpoint to check remaining capacity before making requests, especially for credit-consuming operations (image generation, video generation, AI text).
Monthly limits reset on the 1st of each month. Daily limits reset at midnight UTC. Video credits are granted monthly and don't roll over.
curl https://www.postquick.ai/api/v1/usage \ -H "Authorization: Bearer pq_live_your_key_here"
{
"success": true,
"data": {
"plan": "Pro",
"videoCredits": {
"used": 45,
"limit": 500,
"remaining": 455,
"resetsAt": "2026-04-01T00:00:00Z"
},
"imageGeneration": {
"used": 87,
"limit": 500,
"remaining": 413,
"resetsAt": "2026-04-01T00:00:00Z"
},
"aiTextGeneration": {
"used": 234,
"limit": 2000,
"remaining": 1766,
"resetsAt": "2026-04-01T00:00:00Z"
},
"contentGroups": {
"used": 3,
"limit": "unlimited"
},
"rateLimits": {
"perMinute": {
"used": 12,
"limit": 120,
"remaining": 108,
"resetsAt": "2026-03-25T17:01:00Z"
},
"perDay": {
"used": 450,
"limit": 50000,
"remaining": 49550,
"resetsAt": "2026-03-26T00:00:00Z"
}
}
}
}Plan Comparison
- 100 video credits/month
- 100 image generations/month
- 400 AI text requests/month
- 5 content groups max
- 30 requests/min, 5K requests/day
- 500 video credits/month
- 500 image generations/month
- 2,000 AI text requests/month
- Unlimited content groups
- 120 requests/min, 50K requests/day
Authenticated user info
/v1/meReturns the authenticated API user's identity and entitlement metadata. Use this to confirm which account a key belongs to before making content or publishing requests.
curl https://www.postquick.ai/api/v1/me -H "Authorization: Bearer pq_live_your_key_here"
{
"success": true,
"data": {
"user": {
"id": "user-uuid-123",
"email": "founder@mybrand.com",
"plan": "pro",
"isSubscribed": true,
"apiEnabled": true
}
}
}Manage API keys
/v1/keysLists all API keys for your account. Keys are shown with their prefix (pq_live_abc...), name, last used time, and creation date. Full keys are NEVER returned via API — they're only shown once during creation in the dashboard.
This endpoint also returns account-level entitlement metadata: whether API access is enabled, whether the account is subscribed, and the current plan.
To create or delete keys, use the dashboard at /dashboard/api. This endpoint is read-only for security.
curl https://www.postquick.ai/api/v1/keys \ -H "Authorization: Bearer pq_live_your_key_here"
{
"keys": [
{
"id": "key-uuid-123",
"key_prefix": "pq_live_abc",
"name": "Production API",
"last_used_at": "2026-03-25T16:45:00Z",
"created_at": "2026-01-15T10:00:00Z",
"revoked_at": null,
"isActive": true
},
{
"id": "key-uuid-456",
"key_prefix": "pq_live_xyz",
"name": "Development",
"last_used_at": null,
"created_at": "2026-03-20T14:00:00Z",
"revoked_at": null,
"isActive": true
}
],
"apiEnabled": true,
"isSubscribed": true,
"plan": "pro"
}API analytics
/v1/analyticsReturns detailed analytics for your API usage over the past 30 days: requests by endpoint, requests by API key, error rates, average response times, and daily request volume.
Use this for monitoring, debugging, and optimizing your API integration. Filter analytics with the period query parameter. Supported values: 24h, 7d, 30d, and 90d. Default: 7d.
Parameters
periodstringAnalytics window. One of: 24h, 7d, 30d, 90d. Default: 7d.
curl "https://www.postquick.ai/api/v1/analytics?period=30d" -H "Authorization: Bearer pq_live_your_key_here"
{
"summary": {
"totalRequests": 1247,
"successRate": 96.1,
"avgResponseTime": 342,
"uniqueEndpoints": 12,
"periodStart": "2026-02-24T00:00:00Z",
"periodEnd": "2026-03-25T23:59:59Z"
},
"requestsOverTime": [
{ "date": "2026-03-24", "total": 67, "success": 64, "errors": 3 },
{ "date": "2026-03-25", "total": 89, "success": 86, "errors": 3 }
],
"byEndpoint": [
{ "endpoint": "/v1/posts/generate", "count": 345, "avgMs": 380, "errorRate": 3.5 },
{ "endpoint": "/v1/images/generate", "count": 287, "avgMs": 290, "errorRate": 2.8 }
],
"byStatusCode": [
{ "code": 200, "count": 1198 },
{ "code": 403, "count": 31 },
{ "code": 500, "count": 18 }
],
"byApiKey": [
{ "keyId": "key-uuid-123", "name": "Production API", "count": 892, "lastUsed": "2026-03-25T16:45:00Z" }
],
"recentErrors": [
{ "endpoint": "/v1/videos/generate", "status": 500, "message": "Video generation service failed", "at": "2026-03-25T16:22:00Z" }
],
"rateLimitStatus": {
"plan": "pro",
"minuteLimit": 120,
"minuteUsed": 9,
"dailyLimit": 50000,
"dailyUsed": 1247
}
}Questions about the API? Email us at support@postquick.ai
Get Your API Key →