API Documentation
The Ampost REST API lets you publish, schedule, and manage social media content across 7 platforms from a single integration. All requests use Bearer token authentication and return clean JSON.
AI / LLM ready. This documentation is also available as a machine-readable /llm.txt file, designed for LLMs and AI agents that want to understand the Ampost API.
Overview
Ampost provides a unified social media API. Instead of integrating each platform individually, you connect to Ampost once and get access to instagram, facebook, twitter, linkedin, tiktok, youtube, threads through a single REST API.
Base URL
api.ampost.io
Protocol
HTTPS only
Content Type
application/json
Auth
Bearer token
Rate Limit
Tier-based
Quickstart
Make your first API call in under a minute:
Public REST and MCP traffic is hosted on https://api.ampost.io. The dashboard, OAuth callbacks, and billing/session flows stay on https://ampost.io. Public API paths on https://ampost.io still respond temporarily for backwards compatibility, but new integrations should use the API host.
Get your API key
Sign up at ampost.io, go to Dashboard → Settings → API Keys, and create a new key. Save the raw key — it is shown only once.
Connect a social account
In the dashboard, go to Platforms and connect your social media accounts via OAuth. Create a platform set to group your connections, then reference that platformSetId when creating posts. Use the Accounts endpoints if you need to inspect which active connections are inside a set.
Create a post
curl -X POST https://api.ampost.io/api/v1/posts \
-H "Authorization: Bearer amp_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"content": {
"text": "Hello from the Ampost API!",
"media": [],
"linkUrl": null,
"platformOverrides": {}
},
"platforms": ["threads"],
"scheduledFor": null,
"platformSetId": "set_uuid"
}'Authentication
All API requests require a valid API key passed as a Bearer token in the Authorization header. API keys are created and managed through the Ampost dashboard. Dashboard-only management routes such as /api/keys, billing, and platform OAuth/connection administration do not accept Bearer API keys.
Key format
API keys use the prefix amp_live_ followed by a base64url-encoded random secret. The raw key is shown only once at creation time.
Any valid API key can access the public Ampost API and MCP endpoints that your plan allows. Route-level access is determined by whether an endpoint is part of the public API surface, not by key-level permissions. Ampost API keys are scope-free: the key identifies the owning user, and the endpoint decides whether Bearer-key access is allowed.
Posts
The Posts API is the core of Ampost. Create, retrieve, and manage social media posts across all connected platforms.
/api/v1/postsList posts for the authenticated user. Supports filtering by status and platform, with pagination.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| status | string | No | Filter by post status: draft, scheduled, queued, posting, published, partial, failed, discarded. |
| platform | string | No | Filter by platform: instagram, facebook, twitter, linkedin, tiktok, youtube, threads. |
| limit | integer | No | Maximum number of posts to return (default: 20, max: 100). |
| offset | integer | No | Number of posts to skip for pagination (default: 0). |
{
"posts": [
{
"id": "post_uuid",
"status": "published",
"textPreview": "Building in public...",
"platforms": ["threads", "instagram"],
"mediaCount": 1,
"publishedCount": 2,
"failedCount": 0,
"scheduledFor": null,
"createdAt": "2026-04-30T10:00:00Z",
"updatedAt": "2026-04-30T10:00:00Z",
"platformSetId": "set_uuid"
}
],
"total": 42
}/api/v1/postsCreate a draft or scheduled post with JSON or multipart inline media upload. Publish later with the scheduler or immediately through the versioned publish endpoint.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| content.text | string | Yes | The post text content. |
| content.media | PostMedia[] | No | Array of already-hosted media attachments, or omit it and send files inline with multipart/form-data. TikTok and YouTube require explicit media objects with type, MIME type, sizeBytes, and video durationSeconds when relevant. |
| content.linkUrl | string | null | No | URL to include in the post. |
| content.platformOverrides | object | No | Per-platform overrides (text, settings). Settings supports Instagram/Facebook placement selection, LinkedIn member-post options such as visibility, article metadata, video title, and alt text, TikTok creator controls, and YouTube video settings such as title, description, privacyStatus, publishAt, audience, synthetic-media disclosure, and subscriber notification behavior. |
| platforms | Platform[] | Yes | Array of platforms to publish to. |
| scheduledFor | string | null | No | ISO 8601 timestamp for scheduled posting. null creates a draft. Scheduling is currently supported for Instagram, Facebook, and YouTube; YouTube cannot combine Ampost scheduledFor with platformOverrides.youtube.settings.publishAt. |
| platformSetId | string | Yes | Platform set UUID. The post must be scoped to a platform set. |
{
"post": {
"id": "post_uuid",
"userId": "user_xyz",
"content": { ... },
"platformPosts": [
{
"id": "pp_uuid",
"platform": "threads",
"status": "published",
"publishedUrl": "https://threads.net/user/post/123",
...
}
],
"status": "draft",
"scheduledFor": null,
"createdAt": "2026-04-30T10:00:00Z",
"updatedAt": "2026-04-30T10:00:00Z",
"platformSetId": "set_uuid"
}
}/api/v1/posts/:idGet a single post by ID. Only returns posts belonging to the authenticated user.
/api/v1/posts/:id/cancelCancel a draft, scheduled, queued, partial, or failed post. Published and actively posting posts cannot be cancelled.
/api/v1/posts/:idUpdate a draft or scheduled post. Provide any subset of content, platforms, scheduledFor, or platformSetId.
/api/v1/posts/:idDiscard a post through the primary resource endpoint.
/api/v1/posts/:id/publishPublish a draft or scheduled post immediately to all target platforms.
/api/v1/posts/:id/retryRetry failed platform publishes. Optionally pass a JSON body with a platforms array.
MCP Server
Ampost provides a Model Context Protocol (MCP) server for AI agents and LLMs. The MCP documentation lives on its own page with endpoint details, available tools, and configuration examples.
View MCP Documentation →Platforms
Ampost supports 7 social media platforms through a single integration. Connect your accounts in the dashboard, then reference them by platform name in API requests.
instagramImages, video, carousels
facebookPosts, pages, groups
Twitter/X
twitterPosts, threads
linkedinMember posts only; org posting gated
TikTok
tiktokPhoto and video posts; immediate-only, audit-sensitive visibility
YouTube
youtubeVideo publishing beta
Threads
threadsPosts, replies
YouTube
Ampost's YouTube support is a video-only publishing surface. Requests must include exactly one explicit video object, and the current launch state should be treated as beta unless your Google Cloud project has already cleared YouTube audit requirements for public or unlisted uploads.
Launch state
Beta / audit-sensitive
Media
One video only
Scheduling
Ampost or publishAt
Account discovery
/api/v1/accounts
Google's official videos.insert documentation states that uploads from unverified API projects created after July 28, 2020 stay private until the project passes audit. Ampost can also force this behavior explicitly with YOUTUBE_FORCE_PRIVATE_UPLOADS=true while verification is pending.
Required server setup
Required env vars: YOUTUBE_CLIENT_ID, YOUTUBE_CLIENT_SECRET, YOUTUBE_REDIRECT_URI.
Optional launch-state env: YOUTUBE_FORCE_PRIVATE_UPLOADS to keep requested public or unlisted uploads private until Google review is complete.
Required OAuth scopes: https://www.googleapis.com/auth/youtube.upload and https://www.googleapis.com/auth/youtube.
Quota behavior
As of June 1, 2026, Google documents a separate Video Uploads quota bucket with a default limit of 100 videos.insert calls per day.
Other YouTube Data API methods continue to consume the general daily quota bucket, which defaults to 10,000 units per day.
Invalid requests still consume quota, so validate payloads before repeated retries.
Example JSON request
{
"content": {
"text": "Fallback title for the YouTube upload",
"media": [
{
"url": "https://cdn.example.com/product-demo.mp4",
"type": "video",
"filename": "product-demo.mp4",
"mimeType": "video/mp4",
"sizeBytes": 18432000,
"width": 1920,
"height": 1080,
"durationSeconds": 45,
"thumbnailUrl": "https://cdn.example.com/product-demo-thumb.jpg"
}
],
"linkUrl": null,
"platformOverrides": {
"youtube": {
"settings": {
"title": "Explicit YouTube title",
"description": "Launch walkthrough",
"tags": ["launch", "demo"],
"categoryId": "28",
"privacyStatus": "private",
"notifySubscribers": false,
"selfDeclaredMadeForKids": false,
"containsSyntheticMedia": true
}
}
}
},
"platforms": ["youtube"],
"scheduledFor": null,
"platformSetId": "set_uuid"
}YouTube settings
| Field | Type | Notes |
|---|---|---|
| title | string | Optional override. Falls back to content.text and is required one way or the other. |
| description | string | Optional long-form description. |
| tags | string[] | Optional. Combined tag length must stay within 500 characters. |
| categoryId | string | Optional. Defaults to 22 (People & Blogs) if omitted. |
| privacyStatus | "private" | "unlisted" | "public" | Optional. Defaults to private and may still be forced private during beta launch mode. |
| publishAt | ISO 8601 string | Optional YouTube visibility time. Must be future-dated, requires private privacyStatus, and cannot be combined with Ampost scheduledFor. |
| notifySubscribers | boolean | Optional subscriber notification toggle. |
| selfDeclaredMadeForKids | boolean | Optional audience flag. |
| containsSyntheticMedia | boolean | Optional disclosure flag for realistic AI-generated or altered media. |
Common YouTube validation and publish failures
| Surface | Example | Meaning |
|---|---|---|
| Validation | YouTube video title is required | Provide content.text or platformOverrides.youtube.settings.title. |
| Validation | Choose either Ampost scheduling or YouTube setting "publishAt", not both | Use only one scheduler. |
| Validation | YouTube scheduling requires privacyStatus "private" | publishAt only works for private visibility. |
| Broker | Quota exceeded (quotaExceeded) | Google rejected the request because the Video Uploads or general quota bucket is exhausted. |
| Broker | AUTH_REVOKED / insufficientPermissions | The Google token is missing required scope or the user revoked access. |
Ampost's LinkedIn launch state is member-profile publishing only. The current surface supports text-only posts, image posts, article posts, and one-video posts on behalf of an authenticated member. Organization or Page posting is intentionally gated and is not part of the public launch surface.
Launch state
Member-only
Media
Images, article thumbnail, or one video
Scheduling
Immediate only
Account discovery
/api/v1/accounts
LinkedIn's official Community Management guidance says organization-level access is restricted and available only to registered legal organizations for approved commercial use cases. Ampost therefore keeps organization posting behind an explicit operator gate even though the request schema reserves the fields.
Required server setup
Required env vars: LINKEDIN_CLIENT_ID, LINKEDIN_CLIENT_SECRET, LINKEDIN_REDIRECT_URI, and LINKEDIN_API_VERSION.
Current default version header: Linkedin-Version: 202605. Review this monthly and upgrade before LinkedIn's one-year support window expires.
Requested OAuth scopes: openid, profile, email, and w_member_social.
Provider constraints
LinkedIn documents daily limits per application and per member, both resetting at midnight UTC.
Exact endpoint quotas are not published in the docs; inspect your LinkedIn Developer Portal Analytics tab after the app has made at least one request that day.
If LinkedIn does not return a programmatic refresh token for your app, Ampost surfaces a reconnect-required flow instead of promising silent background refresh forever.
LinkedIn settings and limits
| Field | Type | Notes |
|---|---|---|
| visibility | "PUBLIC" | "CONNECTIONS" | Optional. Defaults to LinkedIn's member-post behavior when omitted. |
| isReshareDisabledByAuthor | boolean | Optional reshare control for member posts. |
| articleTitle | string | Optional article metadata. Requires content.linkUrl. |
| articleDescription | string | Optional article metadata. Requires content.linkUrl. |
| videoTitle | string | Optional title metadata for a single LinkedIn video post. |
| altText | string | string[] | Optional image accessibility text. Arrays must match the image count. |
| authorType | "member" | Organization values are rejected in the public launch surface. |
Common LinkedIn validation and publish failures
| Surface | Example | Meaning |
|---|---|---|
| Validation | LinkedIn organization posting is intentionally gated for a later operator task. | Organization or Page posting is not part of the launch surface. |
| Validation | LinkedIn posts cannot be scheduled yet. | Use immediate publish only. |
| Validation | LinkedIn video URLs must be sent with explicit metadata. | Use content.media rather than bare mediaUrls for video. |
| Broker | LinkedIn did not return a refresh token for this app. Reconnect this account. | The app is not receiving programmatic refresh tokens. |
| Broker | AUTH_EXPIRED / AUTH_REVOKED / RATE_LIMITED | Reconnect or retry according to the provider failure surfaced by Ampost. |
Placement
Instagram and Facebook support placement selection to control how content appears. Placements are set via platformOverrides.{platform}.settings.placement and are validated against the media configuration.
Instagram Placements
feedstoryreelcarouselCarousel requires 2+ images. Reel requires exactly one video. Story supports single image or video. Feed supports single image only.
Facebook Placements
feedstoryreelReel requires exactly one video and Meta currently expects 9:16 media between 4 and 60 seconds. Feed and story support images or video. If Facebook returns identity-confirmation errors, complete the Page authorization flow in the Facebook mobile app before retrying.
Platform Sets
Platform sets group your connected social accounts into named collections. Every post must be scoped to a platform set via platformSetId. Each user can create up to 20 sets.
The public REST surface exposes versioned platform-set endpoints for Bearer API keys. Use them to list sets, create new ones, rename a set, or delete a non-default set. Deleting a set revokes its active platform connections. Dashboard cookie-auth routes remain available separately for the web app.
The canonical public endpoints are /api/v1/platform-sets and /api/v1/platform-sets/:id. The older /api/platforms/sets routes also accept Bearer API keys and dashboard session auth for the same list, create, rename, and delete operations. OAuth connection flows stay outside the public REST and MCP surface: auth URL and callback routes are browser/dashboard entrypoints, while refresh, page selection, and disconnect routes use dashboard session auth rather than Bearer API keys.
/api/v1/platform-setsList all platform sets for the authenticated user. Each set includes a connection count of active platform connections.
{
"sets": [
{
"id": "set_uuid",
"userId": "user_xyz",
"name": "My Brand Accounts",
"isDefault": true,
"createdAt": "2026-04-30T10:00:00Z",
"updatedAt": "2026-04-30T10:00:00Z",
"connectionCount": 3
}
]
}/api/v1/platform-setsCreate a new platform set. Max 20 sets per user.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| name | string | Yes | Display name for the platform set (max 50 characters). |
{
"set": {
"id": "set_uuid",
"userId": "user_xyz",
"name": "My Brand Accounts",
"isDefault": false,
"createdAt": "2026-04-30T10:00:00Z",
"updatedAt": "2026-04-30T10:00:00Z",
"connectionCount": 0
}
}/api/v1/platform-sets/:idRename an existing platform set owned by the authenticated user.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| name | string | Yes | New display name for the platform set (max 50 characters). |
{
"set": {
"id": "set_uuid",
"userId": "user_xyz",
"name": "Renamed Set",
"isDefault": false,
"createdAt": "2026-04-30T10:00:00Z",
"updatedAt": "2026-05-01T12:00:00Z"
}
}/api/v1/platform-sets/:idDelete a platform set. All active connections in the set are revoked. The default set cannot be deleted.
{
"success": true
}Accounts
Use the versioned account endpoints to discover connected publishing accounts before creating or debugging posts.
Account responses include scopes, platform set membership, token expiry, derived tokenHealth, and non-secret platformMetadata. For TikTok this metadata includes creator publish options such as available privacy levels, disabled comment/duet/stitch flags, and max video duration. For YouTube it includes channel identifiers plus the stored channel-title and subscriber/video/view count snapshot captured at connect time. For LinkedIn it includes the member's subject identifier, basic OIDC profile snapshot, granted scopes, auth-flow marker, and the organization-posting gate state captured at connect time.
/api/v1/accountsList connected social accounts. Supports platform and platformSetId filters.
/api/v1/accounts/:idGet details for a single connected account.
Media Upload
Media files are uploaded inline through the public versioned post creation endpoint. Send a multipart/form-data request to /api/v1/posts with a data field (the same JSON body documented for post creation) and one or more files fields (media files). The legacy /api/posts route remains compatible for existing integrations.
/api/v1/postsAccepted MIME types: image/jpeg, image/png, image/webp, video/mp4, video/quicktime. Max file size: 200 MB per file.
curl -X POST https://api.ampost.io/api/v1/posts \
-H "Authorization: Bearer amp_live_YOUR_KEY" \
-F 'data={
"content":{
"text":"TikTok launch post",
"media":[{
"url":"https://cdn.example.com/launch.mp4",
"type":"video",
"filename":"launch.mp4",
"mimeType":"video/mp4",
"sizeBytes":18432000,
"width":1080,
"height":1920,
"durationSeconds":24
}],
"linkUrl":null,
"platformOverrides":{
"tiktok":{"settings":{"privacyLevel":"SELF_ONLY","disableComment":true}}
}
},
"platforms":["tiktok"],
"scheduledFor":null,
"platformSetId":"set_uuid"
}' \
-F "files=@launch.mp4"Scheduled Instagram, Facebook, and YouTube media posts use the same endpoint. Attempts to schedule unsupported platforms such as linkedin, threads, or tiktok return a 400 validation error. For JSON requests, TikTok and YouTube should always be sent as explicit content.media objects. LinkedIn strongly prefers explicit media objects as well and requires them for video. TikTok creator visibility is also launch-state sensitive: if the connected TikTok app is limited to private-only posting during audit or Direct Post review, Ampost exposes only the allowed privacy levels and surfaces provider errors instead of assuming public delivery. YouTube supports exactly one video, does not allow image-only or mixed-media posts, and may keep requested public or unlisted uploads private while Google verification or audit is still pending.
LinkedIn Contract
LinkedIn supports member-auth text-only posts, image posts, article posts, and single-video posts. Use platformOverrides.linkedin.text for a LinkedIn-specific text override and platformOverrides.linkedin.settings for visibility, reshare controls, article metadata, and video title metadata. Organization posting remains intentionally gated, analytics and comment-management APIs are not part of this launch, and LinkedIn scheduling is not supported.
Typed content.media objects are recommended for all LinkedIn media and required for video. Bare mediaUrls stay available only for legacy image posts; video-like legacy URLs are rejected because LinkedIn image and video upload flows differ.
{
"content": {
"text": "Shipping the new LinkedIn contract today.",
"media": [],
"linkUrl": null,
"platformOverrides": {
"linkedin": {
"settings": {
"visibility": "PUBLIC",
"isReshareDisabledByAuthor": true
}
}
}
},
"platforms": ["linkedin"],
"scheduledFor": null,
"platformSetId": "set_uuid"
}{
"content": {
"text": "LinkedIn image post",
"media": [
{
"id": "media-1",
"url": "https://cdn.example.com/product-shot.png",
"type": "image",
"filename": "product-shot.png",
"mimeType": "image/png",
"sizeBytes": 248120,
"width": 1600,
"height": 900,
"altText": "Product dashboard with the LinkedIn publish flow open."
}
],
"linkUrl": null,
"platformOverrides": {
"linkedin": {
"settings": {
"visibility": "CONNECTIONS"
}
}
}
},
"platforms": ["linkedin"],
"scheduledFor": null,
"platformSetId": "set_uuid"
}{
"content": {
"text": "LinkedIn demo clip",
"media": [
{
"id": "media-1",
"url": "https://cdn.example.com/demo.mp4",
"type": "video",
"filename": "demo.mp4",
"mimeType": "video/mp4",
"sizeBytes": 18432000,
"width": 1920,
"height": 1080,
"durationSeconds": 38,
"thumbnailUrl": "https://cdn.example.com/demo-thumb.jpg"
}
],
"linkUrl": null,
"platformOverrides": {
"linkedin": {
"settings": {
"visibility": "PUBLIC",
"videoTitle": "Ampost LinkedIn demo"
}
}
}
},
"platforms": ["linkedin"],
"scheduledFor": null,
"platformSetId": "set_uuid"
}{
"text": "This will be rejected",
"platforms": ["linkedin"],
"scheduledFor": null,
"platformSetId": "set_uuid",
"mediaUrls": ["https://cdn.example.com/demo.mp4"]
}The invalid legacy example returns a 400 validation error because LinkedIn video posts must use explicit media metadata.
Rate Limits
Ampost enforces tier-based rate limiting to ensure fair usage. Rate limits vary by operation and plan. Exceeding a rate limit returns a 429 Too Many Requests response.
Rate limit operations
| Operation | Description |
|---|---|
| createPost | Creating new posts |
| publishPost | Publishing scheduled posts |
| connectPlatform | Adding new platform connections |
| mediaUpload | Uploading media attachments |
| apiRead | Reading posts and account data |
Quota types
In addition to rate limits, Ampost enforces monthly quotas depending on your plan:
postsPerMonthmediaUploadsPerMonthapiRequestsPerMonthmaxScheduledPostsmaxStorageBytesError Codes
The API returns standard HTTP status codes with JSON error bodies. Post-engine errors include a machine-readable code.
| Code | HTTP | Description |
|---|---|---|
VALIDATION_FAILED | 400 | Request body failed validation. |
NO_PLATFORMS_SELECTED | 400 | No platforms specified in the request. |
PLATFORM_NOT_CONNECTED | 400 | Requested platform has no connected account. |
CONTENT_TOO_LONG | 400 | Post text exceeds platform character limits. |
UNSUPPORTED_MEDIA_TYPE | 400 | Media file format is not supported. |
UNSUPPORTED_MEDIA_CONFIG | 400 | Media configuration is not supported by the platform. |
INVALID_PLACEMENT | 400 | Selected placement is invalid for the current media configuration. |
MIXED_MEDIA_NOT_SUPPORTED | 400 | Platform does not support mixing image and video media in a single post. |
PAGE_IDENTITY_CONFIRMATION_REQUIRED | 403 | Facebook requires the Page manager to complete identity confirmation in the Facebook mobile app before publishing can continue. |
POST_NOT_FOUND | 404 | The requested post does not exist. |
INVALID_STATUS_TRANSITION | 409 | Cannot transition the post to the requested status. |
RATE_LIMITED | 429 | Rate limit exceeded. Retry after the window resets. |
MEDIA_UPLOAD_FAILED | 502 | Media upload to platform failed. |
BROKER_ERROR | 502 | Platform broker encountered an internal error. |
Continue browsing
Related implementation paths
Use these nearby pages when you want product context, MCP-specific setup, or plan details alongside the raw API reference.