AthenousDevelopers

Guides

The paths behind the quickstart: connect an account, move a post through its statuses, upload media, and publish ads from the top down.

Connect an account

OAuth stays in the Athenous app. Open Connections, link the network, then list connections with the API key.

curl -sS "https://public-api.athenous.io/api/v1/connectors" \
  -H "X-Api-Key: $ATHENOUS_API_KEY"

Use the returned id as connectorId. Facebook Pages are GET /api/v1/connectors/pages?platform=FACEBOOK. Ad accounts are GET /api/v1/connectors/ad-accounts?platform=META. A Snap public profile id can be updated with PATCH /api/v1/connectors/{id}.

Post lifecycle

Status is one of DRAFT, SCHEDULED, PUBLISHING, PUBLISHED, PARTIAL, FAILED, or CANCELLED. Each channel has its own publication status: PENDING, PUBLISHING, PUBLISHED, or FAILED.

StatusWhat you can do
DRAFTEdit the post. Call approve before you schedule it. Publish sends it now.
SCHEDULEDAthenous publishes at scheduledAt. A channel scheduledAt overrides that time for one network.
PUBLISHINGWait, then read the post again.
PUBLISHEDPull engagement with POST /api/v1/posts/{id}/sync.
PARTIALAt least one channel published and at least one failed. Read publications[].errorMessage, then retry-failed.
FAILEDNo channel published. Fix the channel options and retry.

There is no webhook for these transitions. Poll GET /api/v1/posts/{id} or GET /api/v1/posts/{id}/publications.

Schedule a post

Create the draft, approve it, then set the time. The full request is on the quickstart. Scheduling before approve returns a 4xx whose detail is Approve this draft before it can be scheduled.

curl -sS -X POST "https://public-api.athenous.io/api/v1/posts/$POST_ID/approve" \
  -H "X-Api-Key: $ATHENOUS_API_KEY"

curl -sS -X PUT "https://public-api.athenous.io/api/v1/posts/$POST_ID?status=SCHEDULED" \
  -H "X-Api-Key: $ATHENOUS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"scheduledAt":"2026-03-20T14:00:00Z"}'

Publish now, then retry one network

curl -sS -X POST "https://public-api.athenous.io/api/v1/posts/$POST_ID/publish" \
  -H "X-Api-Key: $ATHENOUS_API_KEY"

curl -sS -X POST "https://public-api.athenous.io/api/v1/posts/$POST_ID/retry-failed" \
  -H "X-Api-Key: $ATHENOUS_API_KEY"

retry-failed sends only the channels whose last publish failed.

Upload media

Networks fetch mediaUrl at publish time. Upload the file first and store the returned URL on the post. The multipart field name is file. The response field is mediaUrl. Files around 90 MiB and larger use POST /api/v1/posts/media/upload-session, then a PUT of the bytes to uploadUrl. The full sequence is on Posts.

MEDIA_URL=$(curl -sS -X POST "https://public-api.athenous.io/api/v1/posts/media" \
  -H "X-Api-Key: $ATHENOUS_API_KEY" \
  -F "file=@./hero.jpg" | jq -r '.mediaUrl')

Extra images for a carousel go in media_urls inside that channel’s settings. Limits are on the platform list.

Publish ads top down

Create the campaign, publish it, then the ad set, then the ad. A key limited to athenous_post receives 403 on these routes. platform values are on the advertising list.

CID=$(curl -sS -X POST "https://public-api.athenous.io/api/v1/campaigns" \
  -H "X-Api-Key: $ATHENOUS_API_KEY" -H "Content-Type: application/json" \
  -d '{"name":"API campaign","platform":"META","objectiveType":"AWARENESS","budgetAllocation":{"META":5000}}' \
  | jq -r '.id')

curl -sS -X POST "https://public-api.athenous.io/api/v1/campaigns/$CID/publish" \
  -H "X-Api-Key: $ATHENOUS_API_KEY" -H "Content-Type: application/json" \
  -d '{"platform":"META","connectorId":"CONNECTOR_UUID","adAccountId":"act_123","facebookPageId":"123456"}'

Create the ad set at POST /api/v1/campaigns/{campaignId}/ad-sets, publish it, then create the ad at POST …/ad-sets/{adSetId}/ads and publish that. Sync metrics with POST …/sync and the same platform and connectorId.

Pages

page starts at 0. size is 1 to 1000, default 20. Posts and campaigns both return content, totalElements, and totalPages. Repeat status to filter posts, for example status=DRAFT&status=SCHEDULED.

Errors and rate limits

Default rate limit is 100 requests per minute per key. batch raises that to 500. 429 includes Retry-After.

CodeWhat to do
401Send X-Api-Key on product routes, or a bearer token on account routes.
403The plan or the key scope does not include this route. A Posts-only key names the Posts scope in detail. An Ads-only key names the Ads scope.
409Quota, a duplicate publish, or a plan limit. Check GET /api/v1/posts/quota/monthly for posts.
422Invalid body, channelSettings, or a missing connectorId.
502The network rejected the publish. Read publications[].errorMessage.

The full code list is in the API reference. Account routes, API keys, sessions, and MFA use a session or bearer token, not X-Api-Key. See Account.