Every API here is available over the APIs.io API and to AI agents over MCP.
MCP server
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
Tools for apis
7 MCP tools reach this
find_apisBrowse and filter every API in the catalog.
get_api_artifactsOne API's artifacts, grouped by type.
get_openapiThe primary OpenAPI for this API.
find_similar_apisAPIs that look like this one.
apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
resolveTurn a domain, URL or GitHub org into the provider it belongs to.
find_cohortsEvery scored population of providers in the catalog.
All 92 tools →
Call it yourself
curl for this page
This API
curl "https://apis.io/api/v1/apis/postonce:postonce-posts-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"
Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.
Get an API key
Free tier, no form to fill in. Signing in shares your email address with us — we
store it to create your key and to recognise you if you sign in with another
provider. See our Privacy Policy and
Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: PostOnce Public Posts API
version: 1.0.0-alpha
description: Public API for PostOnce paid users
servers:
- url: https://postonce.to/api/public
security:
- bearerAuth: []
tags:
- name: Posts
paths:
/v1/posts:
get:
summary: List posts
description: 'Lists the authenticated profile''s posts, newest first: posts created through the API or dashboard, and posts published by workflows (origin `workflow`). Workflow posts are read-only.'
parameters:
- $ref: '#/components/parameters/listLimit'
- $ref: '#/components/parameters/listAfter'
responses:
'200':
description: Posts returned successfully.
content:
application/json:
schema:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/Post'
meta:
type: object
additionalProperties: true
'400':
description: The after cursor is not a post ID or does not match a post.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'401':
description: Missing, invalid, revoked, or expired API key.
content:
application/json:
schema:
$ref: '#/components/schemas/AuthErrorResponse'
tags:
- Posts
operationId: getV1Posts
x-operation-id-source: derived
post:
summary: Create post
description: Creates one logical post that can target multiple connected accounts. Include `publish_at` to schedule it instead of sending immediately.
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- targets
properties:
content:
type: string
example: Shipping the public API today.
external_id:
type: string
nullable: true
example: launch-001
media:
type: array
items:
$ref: '#/components/schemas/MediaInput'
publish_at:
type: string
format: date-time
nullable: true
example: '2026-04-01T14:00:00.000Z'
targets:
type: array
items:
$ref: '#/components/schemas/PostTargetInput'
examples:
immediate:
value:
content: Shipping the public API today.
external_id: launch-001
targets:
- account_id: account-1
- account_id: account-2
content_override: Shorter version for X
mediaSingle:
value:
content: Launching with a hero image.
media:
- url: https://cdn.example.com/launch-image.png
type: image
width: 1200
height: 630
targets:
- account_id: account-1
mediaMultiple:
value:
content: Carousel post with multiple images.
media:
- url: https://cdn.example.com/carousel-1.png
type: image
- url: https://cdn.example.com/carousel-2.png
type: image
- url: https://cdn.example.com/carousel-3.png
type: image
targets:
- account_id: account-1
perTargetCustomization:
value:
content: Shipping the public API today.
targets:
- account_id: twitter-account-id
content_override: Shipping today. API is live.
- account_id: linkedin-account-id
platform_options:
title: Public API launch
scheduled:
value:
content: Scheduled launch note
publish_at: '2026-04-01T14:00:00.000Z'
targets:
- account_id: account-1
responses:
'201':
description: Post created successfully.
content:
application/json:
schema:
type: object
properties:
data:
$ref: '#/components/schemas/Post'
'400':
description: One or more target accounts are invalid or inactive.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'401':
description: Missing, invalid, revoked, or expired API key.
content:
application/json:
schema:
$ref: '#/components/schemas/AuthErrorResponse'
tags:
- Posts
operationId: postV1Posts
x-operation-id-source: derived
/v1/posts/{id}:
get:
summary: Get post
description: Returns one aggregate post with per-target delivery state.
parameters:
- $ref: '#/components/parameters/postId'
responses:
'200':
description: Post returned successfully.
content:
application/json:
schema:
type: object
properties:
data:
$ref: '#/components/schemas/Post'
'400':
description: Post ID must be a valid UUID.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'401':
description: Missing, invalid, revoked, or expired API key.
content:
application/json:
schema:
$ref: '#/components/schemas/AuthErrorResponse'
tags:
- Posts
operationId: getV1PostsById
x-operation-id-source: derived
patch:
summary: Update post
description: Updates a scheduled post before it runs.
parameters:
- $ref: '#/components/parameters/postId'
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
content:
type: string
external_id:
type: string
nullable: true
media:
type: array
items:
$ref: '#/components/schemas/MediaInput'
publish_at:
type: string
format: date-time
nullable: true
targets:
type: array
items:
$ref: '#/components/schemas/PostTargetInput'
examples:
reschedule:
value:
publish_at: '2026-04-02T15:00:00.000Z'
changeContent:
value:
content: Updated launch copy.
external_id: launch-002
responses:
'200':
description: Scheduled post updated successfully.
content:
application/json:
schema:
type: object
properties:
data:
$ref: '#/components/schemas/Post'
'400':
description: Post ID must be a valid UUID.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'401':
description: Missing, invalid, revoked, or expired API key.
content:
application/json:
schema:
$ref: '#/components/schemas/AuthErrorResponse'
'409':
description: Post can no longer be updated in its current state.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
tags:
- Posts
operationId: patchV1PostsById
x-operation-id-source: derived
delete:
summary: Delete post
description: Cancels a scheduled or still-pending post without deleting its aggregate record or already published social content. This is functionally equivalent to cancel_post.
parameters:
- $ref: '#/components/parameters/postId'
responses:
'200':
description: Scheduled post cancelled successfully.
content:
application/json:
schema:
type: object
properties:
data:
$ref: '#/components/schemas/Post'
'400':
description: Post ID must be a valid UUID.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'401':
description: Missing, invalid, revoked, or expired API key.
content:
application/json:
schema:
$ref: '#/components/schemas/AuthErrorResponse'
tags:
- Posts
operationId: deleteV1PostsById
x-operation-id-source: derived
/v1/posts/{id}/publish:
post:
summary: Publish now
description: Starts publishing a scheduled post immediately and returns the aggregate in processing state.
parameters:
- $ref: '#/components/parameters/postId'
responses:
'200':
description: Publish-now started successfully. The returned post is no longer scheduled.
content:
application/json:
schema:
type: object
properties:
data:
$ref: '#/components/schemas/Post'
'400':
description: Post ID must be a valid UUID.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'401':
description: Missing, invalid, revoked, or expired API key.
content:
application/json:
schema:
$ref: '#/components/schemas/AuthErrorResponse'
tags:
- Posts
operationId: postV1PostsByIdPublish
x-operation-id-source: derived
/v1/posts/{id}/cancel:
post:
summary: Cancel post
description: Cancels a scheduled or still-pending post without deleting its aggregate record or already published social content.
parameters:
- $ref: '#/components/parameters/postId'
responses:
'200':
description: Scheduled post cancelled successfully.
content:
application/json:
schema:
type: object
properties:
data:
$ref: '#/components/schemas/Post'
'400':
description: Post ID must be a valid UUID.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'401':
description: Missing, invalid, revoked, or expired API key.
content:
application/json:
schema:
$ref: '#/components/schemas/AuthErrorResponse'
tags:
- Posts
operationId: postV1PostsByIdCancel
x-operation-id-source: derived
/v1/posts/{id}/targets/{targetId}/retry:
post:
summary: Retry failed destination
description: Retries one failed immediate or scheduled destination without replaying successful, submitted, or published siblings.
parameters:
- $ref: '#/components/parameters/postId'
- $ref: '#/components/parameters/targetPostId'
responses:
'202':
description: Destination retry accepted.
content:
application/json:
schema:
type: object
properties:
data:
$ref: '#/components/schemas/Post'
'400':
description: Post ID must be a valid UUID.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'401':
description: Missing, invalid, revoked, or expired API key.
content:
application/json:
schema:
$ref: '#/components/schemas/AuthErrorResponse'
'409':
description: The destination is not failed or is already being retried.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
tags:
- Posts
operationId: postV1PostsByIdTargetsByTargetIdRetry
x-operation-id-source: derived
components:
schemas:
AuthErrorResponse:
type: object
properties:
error:
type: object
properties:
hint:
type: string
description: Suggested action to resolve the error.
code:
type: string
example: invalid_api_key
message:
type: string
example: Invalid API key.
Post:
type: object
properties:
id:
type: string
content:
type: string
external_id:
type: string
nullable: true
media:
type: array
items:
$ref: '#/components/schemas/MediaInput'
origin:
type: string
enum:
- ui
- api
- workflow
nullable: true
publish_at:
type: string
format: date-time
nullable: true
status:
type: string
enum:
- queued
- scheduled
- processing
- partial
- published
- failed
- cancelled
example: scheduled
created_at:
type: string
format: date-time
nullable: true
targets:
type: array
items:
$ref: '#/components/schemas/PostTarget'
PostTargetInput:
type: object
required:
- account_id
properties:
account_id:
type: string
content_override:
type: string
nullable: true
platform_options:
type: object
additionalProperties: true
nullable: true
properties:
ai_generated:
type: boolean
description: Requests the target platform's native AI-generated or synthetic-media disclosure. Supported for TikTok direct videos, YouTube videos, and Instagram media. Facebook Page publishing does not currently expose an equivalent API field.
channel_id:
type: string
description: Farcaster channel ID for the cast.
video_cover_timestamp_ms:
type: integer
minimum: 0
description: TikTok direct video posts only. Selects the frame at this position, in milliseconds, as the video cover. When set, it takes precedence over media[].thumbnail_url for that TikTok target. Not supported for photo posts or draft uploads.
title:
type: string
description: Title for platforms that support one. For Vimeo, 1-128 characters; defaults to the first line of the content.
privacy_view:
type: string
enum:
- anybody
- unlisted
- nobody
- disable
default: anybody
description: Vimeo only. Who can view the uploaded video.
reply_to:
type: object
nullable: true
required:
- hash
- author_fid
properties:
hash:
type: string
author_fid:
type: integer
description: Farcaster parent cast. Both the full cast hash and parent author FID are required.
disable_notification:
type: boolean
description: Telegram only. Sends the channel post silently; subscribers get no notification sound.
protect_content:
type: boolean
description: Telegram only. Prevents forwarding and saving of the channel post.
disable_link_preview:
type: boolean
description: Telegram only. Disables the link preview on text posts.
description: 'Platform-specific settings are mapped explicitly; unknown properties are stored but are not forwarded automatically. For Farcaster, pass { "channel_id": "founders" } or { "reply_to": { "hash": "0x...", "author_fid": 123 } }. To request native AI-content disclosure on TikTok, YouTube, or Instagram, pass { "ai_generated": true }. Facebook Page publishing does not currently expose an equivalent API field. For Reddit, pass { "subreddit": "SideProject", "title": "Launch title", "postType": "self" }. For Snapchat, pass { "placements": ["spotlight", "public_story"], "locale": "en_US" }; placements default to Spotlight. For a TikTok draft upload, pass { "publish_mode": "draft" }; the creator must finish and publish it from their TikTok inbox. To choose a TikTok cover frame instead of a cover image, pass { "video_cover_timestamp_ms": 1500 }. For Vimeo, pass { "title": "Launch video", "privacy_view": "unlisted" }; privacy_view defaults to anybody. Telegram accepts only { "disable_notification", "protect_content", "disable_link_preview" } booleans and rejects other keys.'
MediaInput:
type: object
required:
- url
properties:
url:
type: string
description: Required absolute HTTP or HTTPS media URL. Surrounding whitespace is trimmed. Invalid URLs reject the entire request with invalid_media; URL contents are not fetched during validation.
example: https://cdn.example.com/launch-image.png
type:
type: string
enum:
- image
- video
example: image
width:
type: integer
height:
type: integer
size:
type: integer
duration:
type: number
description: Video duration in seconds when known.
thumbnail_url:
type: string
description: Cover image URL for video media (JPEG or PNG, 8 MB or less). It is applied as the video cover on Instagram Reels and Stories, Facebook Reels, and TikTok (inserted as the video's first frame), and is also used in scheduled and published post previews.
PostTarget:
type: object
properties:
target_post_id:
type: string
account_id:
type: string
nullable: true
platform:
type: string
nullable: true
target_variant:
type: string
enum:
- spotlight
- public_story
nullable: true
description: Concrete placement for platforms that fan one account target into multiple publications.
username:
type: string
nullable: true
status:
type: string
enum:
- pending
- scheduled
- processing
- submitted
- published
- failed
- skipped
- cancelled
example: pending
error:
type: string
nullable: true
platform_post_id:
type: string
nullable: true
platform_post_url:
type: string
nullable: true
scheduled_time:
type: string
format: date-time
nullable: true
ErrorResponse:
type: object
properties:
error:
type: object
required:
- code
- message
properties:
hint:
type: string
description: Suggested action to resolve the error.
code:
type: string
example: workflow_limit_reached
message:
type: string
example: You have reached the maximum number of workflows for your plan.
parameters:
listLimit:
name: limit
in: query
required: false
schema:
type: integer
minimum: 1
maximum: 100
description: Maximum number of items to return.
postId:
name: id
in: path
required: true
schema:
type: string
format: uuid
description: Aggregate post ID.
listAfter:
name: after
in: query
required: false
schema:
type: string
description: Cursor returned by a previous list response.
targetPostId:
name: targetId
in: path
required: true
schema:
type: string
description: Concrete destination row ID from `data.targets[].target_post_id`.
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: API Key
description: Scoped API key issued in PostOnce Settings. OAuth authorization grants are not currently supported.
x-scopes:
accounts:read: List and read connected accounts.
accounts:write: Connect and disconnect social accounts.
media:read: Read uploaded media.
media:write: Upload media.
posts:read: Read posts and unpublished drafts.
posts:write: Create, update, publish, cancel, retry, and delete posts and drafts.
workflows:read: List and read crossposting workflows.
workflows:write: Create, update, and delete crossposting workflows.