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/postlake-dev:postlake-dev-channels-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
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: PostLake Channels API
version: 1.0.0
description: Unified social media API. One API key, 10 platforms, normalised responses. Built for agents and developers.
contact:
url: https://postlake.dev
servers:
- url: https://api.postlake.dev
security:
- bearerAuth: []
tags:
- name: Channels
paths:
/v1/social-accounts/{id}/webhook:
post:
tags:
- Channels
summary: Subscribe this channel to webhooks
description: 'Some networks need the subscription on the ACCOUNT as well as the app. Facebook is the case: subscribing the app is not enough, the Page has to be subscribed too or nothing is ever delivered, however well the callback is configured. Defaults to feed, mention and messages.'
parameters:
- name: id
in: path
required: true
schema:
type: string
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
fields:
type: array
items:
type: string
description: Which events to subscribe to. Defaults to feed, mention, messages.
responses:
'200':
description: Subscribed
content:
application/json:
schema:
type: object
properties:
subscribed:
type: boolean
fields:
type: array
items:
type: string
required:
- subscribed
- fields
operationId: postV1SocialAccountsByIdWebhook
x-operation-id-source: derived
get:
tags:
- Channels
summary: What this channel is subscribed to
description: The events this channel currently receives, so "we are not getting webhooks" has an answer. A network that does not need a per account subscription returns an empty list.
parameters:
- name: id
in: path
required: true
schema:
type: string
responses:
'200':
description: Subscriptions
content:
application/json:
schema:
type: object
properties:
fields:
type: array
items:
type: string
required:
- fields
operationId: getV1SocialAccountsByIdWebhook
x-operation-id-source: derived
/v1/social-accounts/{id}/posts:
get:
tags:
- Channels
summary: This channel's own posts, from the network
description: 'The account''s own posts read live from the network, including ones published outside PostLake. Different from GET /v1/posts, which lists what PostLake itself published: an account with existing history has posts we never sent, and this is how to reach them.'
parameters:
- name: id
in: path
required: true
schema:
type: string
- name: cursor
in: query
required: false
schema:
type: string
- name: limit
in: query
required: false
schema:
type: integer
minimum: 1
maximum: 50
responses:
'200':
description: Posts
content:
application/json:
schema:
type: object
properties:
items:
type: array
items:
$ref: '#/components/schemas/DiscoveredPost'
cursor:
type: string
nullable: true
platform:
$ref: '#/components/schemas/Platform'
required:
- items
- cursor
- platform
operationId: getV1SocialAccountsByIdPosts
x-operation-id-source: derived
/v1/social-accounts/{id}/tagged:
get:
tags:
- Channels
summary: Posts other people tagged you in
description: Media published by SOMEBODY ELSE that tagged this account. Different from a mention, which names you in text, and different from your own posts. This is what other people said about you, which is usually the thing worth watching.
parameters:
- name: id
in: path
required: true
schema:
type: string
- name: cursor
in: query
required: false
schema:
type: string
- name: limit
in: query
required: false
schema:
type: integer
minimum: 1
maximum: 50
responses:
'200':
description: Tagged posts
content:
application/json:
schema:
type: object
properties:
items:
type: array
items:
$ref: '#/components/schemas/DiscoveredPost'
cursor:
type: string
nullable: true
platform:
$ref: '#/components/schemas/Platform'
required:
- items
- cursor
- platform
operationId: getV1SocialAccountsByIdTagged
x-operation-id-source: derived
/v1/social-accounts/{id}/allowance:
get:
tags:
- Channels
summary: Publishing headroom left
description: 'How many posts this channel has left in the network''s own rolling window, read from the network rather than counted locally. Check it before planning a batch: the alternative is discovering the ceiling by being refused partway through one, with some posts already live and some not.'
parameters:
- name: id
in: path
required: true
schema:
type: string
responses:
'200':
description: Allowance
content:
application/json:
schema:
type: object
properties:
used:
type: integer
limit:
type: integer
remaining:
type: integer
windowHours:
type: integer
description: The window the count covers, so "5 left" means something.
platform:
$ref: '#/components/schemas/Platform'
required:
- used
- limit
- remaining
- windowHours
- platform
operationId: getV1SocialAccountsByIdAllowance
x-operation-id-source: derived
/v1/social-accounts/{id}/ad-accounts:
get:
tags:
- Channels
summary: Ad account lookup (deferred)
description: Unavailable for Facebook and Instagram while PostLake defers Meta advertising features. Returns HTTP 501 with code meta_ads_deferred, not an empty account list. Reconnecting or using an older token will not enable it. The former success schema is retained for client compatibility.
parameters:
- name: id
in: path
required: true
schema:
type: string
responses:
'200':
description: Reserved success shape; unavailable for Facebook and Instagram while deferred
content:
application/json:
schema:
type: object
properties:
business:
type: object
nullable: true
description: 'The business that owns the Page behind this channel. Named because several things hang off it: creator marketplace requires THIS business to be verified, and ad accounts belong to it. Without it, checking the right business in Business Settings is guesswork.'
properties:
id:
type: string
name:
type: string
nullable: true
verified:
type: boolean
nullable: true
description: Null when the network does not say.
adAccounts:
type: array
items:
type: object
properties:
id:
type: string
name:
type: string
currency:
type: string
nullable: true
status:
type: string
nullable: true
description: Only an active account can be spent against.
required:
- id
- name
required:
- adAccounts
'501':
description: Feature deferred. Returns error.type=not_implemented, error.code=meta_ads_deferred and retryable=false. Reconnecting will not enable it.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
operationId: getV1SocialAccountsByIdAdAccounts
x-operation-id-source: derived
/v1/social-accounts/{id}/branded-partners:
get:
tags:
- Channels
summary: Branded partner lookup (deferred)
description: 'Unavailable for Facebook and Instagram: these partner lookups depend on deferred Meta advertising permissions. Returns HTTP 501 with code meta_ads_deferred. This does not remove non-ad branded-content publishing permissions or ordinary tagged-post reads. The former success schema is retained for client compatibility.'
parameters:
- name: id
in: path
required: true
schema:
type: string
responses:
'200':
description: Reserved success shape; unavailable for Facebook and Instagram while deferred
content:
application/json:
schema:
type: object
properties:
partners:
type: array
items:
type: object
properties:
id:
type: string
handle:
type: string
canPromote:
type: boolean
nullable: true
required:
- id
- handle
- canPromote
required:
- partners
'501':
description: Feature deferred. Returns error.type=not_implemented, error.code=meta_ads_deferred and retryable=false. Reconnecting will not enable it.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
operationId: getV1SocialAccountsByIdBrandedPartners
x-operation-id-source: derived
/v1/social-accounts/{id}/partnership-permissions:
get:
tags:
- Channels
summary: Facebook Partnership Ads permissions (deferred)
description: Unavailable while PostLake defers Meta advertising features. Returns HTTP 501 with code meta_ads_deferred without contacting Meta. Reconnecting will not enable it. The former success schema is retained for client compatibility.
parameters:
- name: id
in: path
required: true
schema:
type: string
- name: direction
in: query
schema:
type: string
enum:
- sent
- received
default: sent
responses:
'200':
description: Reserved success shape; unavailable while deferred
content:
application/json:
schema:
type: object
properties:
items:
type: array
items:
type: object
properties:
id:
type: string
partnerPageId:
type: string
status:
type: integer
description: 1 pending; 2 or 7 approved; 3 rejected; 4 revoked; 5 self-removed; 6 cancelled.
direction:
type: string
enum:
- sent
- received
createdAt:
type: string
nullable: true
required:
- id
- partnerPageId
- status
- direction
- createdAt
required:
- items
'501':
description: Feature deferred. Returns error.type=not_implemented, error.code=meta_ads_deferred and retryable=false. Reconnecting will not enable it.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
operationId: getV1SocialAccountsByIdPartnershipPermissions
x-operation-id-source: derived
post:
tags:
- Channels
summary: Act on a Facebook Partnership Ads permission (deferred)
description: Unavailable while PostLake defers Meta advertising features. Returns HTTP 501 with code meta_ads_deferred. No request is sent to Meta and no partner is notified. The former success schema is retained for client compatibility.
parameters:
- name: id
in: path
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
partnerPageId:
type: string
pattern: ^[0-9]+$
action:
type: string
enum:
- send-request
- cancel-request
- accept-request
- reject-request
- remove-permission
required:
- partnerPageId
- action
responses:
'200':
description: Reserved success shape; unavailable while deferred
content:
application/json:
schema:
type: object
properties:
partnerPageId:
type: string
permissionId:
type: string
nullable: true
status:
type: integer
nullable: true
action:
type: string
required:
- partnerPageId
- permissionId
- status
- action
'501':
description: Feature deferred. Returns error.type=not_implemented, error.code=meta_ads_deferred and retryable=false. Reconnecting will not enable it.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
operationId: postV1SocialAccountsByIdPartnershipPermissions
x-operation-id-source: derived
/v1/social-accounts/{id}/branded-content-posts:
get:
tags:
- Channels
summary: Facebook branded-content posts (deferred)
description: Unavailable because this read requires the deferred facebook_branded_content_ads_brand permission. Returns HTTP 501 with code meta_ads_deferred without contacting Meta. Ordinary tagged-post reads are unaffected. The former success schema is retained for client compatibility.
parameters:
- name: id
in: path
required: true
schema:
type: string
- name: startDate
in: query
schema:
type: string
format: date
- name: endDate
in: query
schema:
type: string
format: date
responses:
'200':
description: Reserved success shape; unavailable while deferred
content:
application/json:
schema:
type: object
properties:
items:
type: array
items:
type: object
properties:
postId:
type: string
creatorPageId:
type: string
creatorPageName:
type: string
createdAt:
type: string
nullable: true
required:
- postId
- creatorPageId
- creatorPageName
- createdAt
required:
- items
'501':
description: Feature deferred. Returns error.type=not_implemented, error.code=meta_ads_deferred and retryable=false. Reconnecting will not enable it.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
operationId: getV1SocialAccountsByIdBrandedContentPosts
x-operation-id-source: derived
/v1/social-accounts/{id}/events:
post:
tags:
- Channels
summary: Create a scheduled event
description: Create an event on the account, where the network allows it through the API. Instagram calls this a reminder and normally expects it to be added while composing a post in the app; this asks the API directly, and a network that refuses says so in its own words. The returned id goes in the `upcomingEventId` post option.
parameters:
- name: id
in: path
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- title
- startsAt
properties:
title:
type: string
startsAt:
type: string
format: date-time
endsAt:
type: string
format: date-time
responses:
'201':
description: Created
content:
application/json:
schema:
type: object
properties:
id:
type: string
title:
type: string
startsAt:
type: string
nullable: true
endsAt:
type: string
nullable: true
required:
- id
- title
operationId: postV1SocialAccountsByIdEvents
x-operation-id-source: derived
get:
tags:
- Channels
summary: Scheduled events on this channel
description: Events scheduled on the account (a launch, a drop, a live), whose id goes in the `upcomingEventId` post option to put a reminder button on the post. Events are created in the network's own app; this reads them. Instagram needs a connection made through Facebook. A network without events returns an empty list.
parameters:
- name: id
in: path
required: true
schema:
type: string
responses:
'200':
description: Events
content:
application/json:
schema:
type: object
properties:
items:
type: array
items:
type: object
properties:
id:
type: string
description: Pass this in the upcomingEventId post option.
title:
type: string
startsAt:
type: string
nullable: true
endsAt:
type: string
nullable: true
required:
- id
- title
cursor:
type: string
nullable: true
required:
- items
- cursor
operationId: getV1SocialAccountsByIdEvents
x-operation-id-source: derived
/v1/social-accounts/{id}/products:
get:
tags:
- Channels
summary: Shoppable products on this channel
description: The account's own shop catalogue, so you can find the product ids the `productIds` post option takes. Only networks with a shop answer; anything else returns an empty list rather than an error, because "nothing to tag" is a true answer to the question. Instagram needs an approved Shop and a catalogue on the same business.
parameters:
- name: id
in: path
required: true
schema:
type: string
- name: q
in: query
required: false
schema:
type: string
description: Filter by product name.
- name: cursor
in: query
required: false
schema:
type: string
- name: limit
in: query
required: false
schema:
type: integer
minimum: 1
maximum: 100
responses:
'200':
description: Products
content:
application/json:
schema:
type: object
properties:
items:
type: array
items:
type: object
properties:
id:
type: string
description: Pass this in the productIds post option.
name:
type: string
imageUrl:
type: string
nullable: true
price:
type: string
nullable: true
status:
type: string
nullable: true
description: Only approved products can be tagged on a post.
required:
- id
- name
cursor:
type: string
nullable: true
required:
- items
- cursor
operationId: getV1SocialAccountsByIdProducts
x-operation-id-source: derived
components:
schemas:
ErrorResponse:
type: object
properties:
error:
$ref: '#/components/schemas/NormalisedError'
required:
- error
NormalisedError:
type: object
description: '`type` is the coarse category you route on and is deliberately small, so it cannot say WHICH input was wrong. `code`, `fix`, `docs` and `param` are what turn a rejection into something a caller can act on rather than guess at. They are optional only in the sense that not every error has all four.'
properties:
type:
type: string
description: Coarse category to route on, e.g. rate_limited, auth_expired, platform_rejected.
message:
type: string
platform:
oneOf:
- $ref: '#/components/schemas/Platform'
- type: 'null'
retryable:
type: boolean
code:
type: string
description: Stable, granular handle to branch on, e.g. text_too_long. Also the anchor in the error reference.
fix:
type: string
description: The next action, in plain words. Safe to show a person as-is.
docs:
type: string
format: uri
description: Where the rule is written down, so it is learned once rather than rediscovered.
param:
type: string
description: The request field at fault, so a form can mark the right input.
required:
- type
- message
- retryable
SocialActor:
type: object
properties:
handle:
type: string
displayName:
type: string
nullable: true
avatarUrl:
type: string
nullable: true
id:
type: string
nullable: true
description: The network's own id, for follow/block/mute
Platform:
type: string
enum:
- bluesky
- threads
- x
- linkedin
- instagram
- tiktok
- facebook
- youtube
- pinterest
DiscoveredPost:
type: object
description: 'A post found by searching or browsing, rather than one you published. Deliberately not the Post shape: far less is known about someone else''s post, and a shape full of nulls invites you to assume they are readable.'
properties:
id:
type: string
platform:
type: string
author:
$ref: '#/components/schemas/SocialActor'
text:
type: string
createdAt:
type: string
format: date-time
url:
type: string
nullable: true
mediaType:
type: string
enum:
- text
- image
- video
- other
description: '''other'' keeps a new network media type from breaking a parser that switches on this.'
isReply:
type: boolean
isQuote:
type: boolean
authorHidden:
type: boolean
description: 'True when the network REFUSES to name the author, as opposed to us failing to read it. Instagram hashtag results are the case: Meta rejects the username field on media returned by a tag search, so author.handle is necessarily empty. Treat an empty handle WITHOUT this flag as a bug; with it, as the network''s rule.'