Ocoya
API

Build social publishing into your product.

A clean REST API with a published OpenAPI spec lets you embed AI-powered social publishing into any app, workflow or agent you build.

POST /v1/post
curl -X POST https://app.ocoya.com/api/_public/v1/post \
-H "X-API-Key: $OCOYA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"socialProfileIds": ["sp_8f2a1c"],
"caption": "New summer menu is here ☀️",
"media": ["https://cdn.example.com/summer.jpg"],
"scheduledAt": "2026-09-01T09:00:00Z"
}'
201 Created
{
"id": "post_8f2a1c",
"status": "SCHEDULED",
"scheduledAt": "2026-09-01T09:00:00Z"
}

Clean REST + OpenAPI

Predictable REST resources with a published OpenAPI spec — generate a client in any language.

API key auth

Send an X-API-Key header — create and revoke keys per brand from your settings.

AI included

The same AI post and campaign generation the app uses, callable from your backend.

Same engine as the app

Every endpoint mirrors what powers Ocoya itself — nothing held back.

OpenAPI

A spec you can generate a client from.

The whole v1 surface ships as an OpenAPI document, so you are not reading prose and writing request objects by hand. Generate a typed client in the language you already work in, or point Postman, Insomnia or your own tooling straight at it.

  • Typed clients in any language the generators support
  • Request and response shapes stay in sync with the API
  • Drop it into your existing API tooling unchanged
openapi.jsonv1
{
"openapi": "3.1.0",
"paths": {
"/v1/post": { ... },
"/v1/campaigns": { ... }
}
}
TypeScriptPythonGoRubyPHPJava

Generate a typed client in whatever you already write, or point your API tooling straight at the spec.

Async by default

Long jobs return straight away.

AI campaign generation is queued rather than run inside your request. The call comes back with a campaign id straight away; poll the resource and the posts fill in as they are written, so nothing in your app sits waiting on a model.

  • Campaign creation answers immediately with an id
  • Poll the campaign resource to watch posts appear
  • AI generation draws on the same credits as the app
POST /v1/campaignsgenerating
// returns immediately
{ "id": "cmp_8fa2", "status": "generating", "posts": 8 }
Post 1 — Instagram
Post 2 — LinkedIn
Post 3 — X
Post 4 — Instagram
Post 5 — TikTok

The call returns immediately. Poll the campaign resource and the posts appear as they generate — nothing blocks your request thread.

Resources

Everything the app can do, callable directly.

Eight REST resources cover the full platform — publishing, AI campaigns, brand assets, workflows and brands.

/v1/post

Create, schedule, update and publish posts across connected networks.

/v1/campaigns

Queue AI campaign generation and track posts as they fill in.

/v1/social-profiles

List connected profiles and start new social connections.

/v1/hashtag-libraries

Fetch curated hashtag sets to attach to posts programmatically.

/v1/studio-templates

List reusable Studio design templates for new content.

/v1/workflow

Inspect, toggle and run automation workflows on demand.

/v1/brands

Enumerate brands and scope every call correctly.

/v1/me

Introspect the token — who am I, and what can I access?

Post lifecycle

You always know where a post is.

Every post carries one of eight statuses, and you can filter on any of them. Poll a campaign while it generates, hold posts behind approval, or alert your own systems the moment something needs a human.

Failures never disappear quietly — NEEDS_ATTENTION and ERROR carry the reason the network gave, so you can surface it in your own UI.

GET /v1/post?statuses=

8 values
GENERATING
DRAFT
PENDING_INTERNAL_APPROVAL
PENDING_CLIENT_APPROVAL
SCHEDULED
POSTED
NEEDS_ATTENTION
ERROR

Requests this window

60s

RateLimit-Limit

60

RateLimit-Remaining

17

RateLimit-Reset

38

429 Too Many Requests
{
"message": "You've exceeded the request limit."
}
Limits

Predictable limits, standard headers.

60 requests per minute by default. Every response carries the standard RateLimit-* headers, so your client can back off before it ever gets a 429 — no guessing, no undocumented throttling.

Read the remaining budget from every responseA 429 tells you exactly when to retryBulk publishing runs server-side, not request-by-request
Onboarding

Let your users connect their own accounts.

Ask for a connection URL and hand it to your user. They approve on the network itself, and the profile lands in your brand ready to publish to — you never touch a social token, and they never see Ocoya.

This is what makes the API viable for a product with customers of its own, rather than just for automating your own account.

1Your appPOST /v1/social-profiles/connection-url
2OcoyaReturns a one-time OAuth start URL
3Your userApproves on Instagram, X, LinkedIn…
4Your appProfile appears in /v1/social-profiles

Your users never see an Ocoya login — the connection lands in your brand.

Building an AI agent instead?

The same platform is exposed over MCP — 20+ tools your agent can call directly, no REST glue code required.

Explore MCP
Questions

The API, answered.

Create an API key in Settings → API and send it in the X-API-Key header against the base URL https://app.ocoya.com/api/_public/v1. Keys are scoped per brand and can be revoked at any time — keep them server-side.

Start building social publishing in.

Grab your API token and make your first call in minutes.