Product documentationUpdated 2026-11-1113 min read2,657 words

Asteria Engine API

Use API keys to work in an Asteria Engine workspace from your own tools: read posts and analytics, create drafts, generate and plan content, and send posts for approval.

Overview

The Asteria Engine API lets your own tools work in an Asteria Engine workspace: a client reporting dashboard, an automation in Zapier or Make, your CRM, or a script your team writes. It can read posts, analytics and brand settings, create drafts, add media, have Asteria write and design posts, plan content, and send posts for approval.

The API and webhooks are included on the Agency and Enterprise plans.

Nothing the API does publishes on its own. Drafts and generated posts wait in the workspace, and the workspace's approval rules decide what goes out, exactly as they do for your team.

Create an API key

  1. Open Settings, then API & Webhooks (turn on Show all tools at the bottom of the menu if you can't see it).
  2. Select Create key.
  3. Give it a name that says what it's for, such as "Client reporting dashboard".
  4. Choose what it may do:
    • See posts, brand settings, the content strategy, connected accounts, analytics and credits
    • Create drafts, add media, and change the content strategy and brand profile once you agree
    • Create content and content plans with Asteria Engine (designing spends credits)
    • Send posts for approval, approve them and schedule them (your approval rules still apply)
    • See and run paid ads within your workspace's spending limits
  5. Choose when it expires, then select Create key.
  6. Copy the key straight away. It is shown only once. If you lose it, revoke it and create another.

Workspace owners and managers can create and revoke keys. A key:

  • works in the workspace it was created in, and no other;
  • acts as the person who created it, with their permissions;
  • stops working when it is revoked, when it expires, if its creator leaves the workspace, or if the workspace's plan no longer includes the API.

Create one key per tool or client integration, so you can revoke any of them without affecting the rest.

Make a request

Send the key in the Authorization header of every request. The address of the API is shown in Settings › API & Webhooks.

curl https://mcp.asteriaengine.com/api/public/v1/posts/ \
  -H "Authorization: Bearer ae_live_..."

Requests and responses are JSON, and field names are camelCase (for example pageSize, scheduledFor).

What you can do

EndpointWhat it doesPermission
GET /workspace/The key's workspaceSee
GET /workspace/brand/Brand voice, audience, offerings and rulesSee
PATCH /workspace/brand/Change the brand profile (changes, confirmed); needs a person who can manage settingsCreate drafts
GET /accounts/Connected social accountsSee
GET /credits/Credits left this periodSee
GET /posts/Posts, filtered by status and search, paginatedSee
GET /posts/{id}/One postSee
POST /posts/Create a draft (caption, optional platformAccountId, mediaIds, hashtags, proposedTime)Create drafts
GET /media/Media library, filtered by type and search, paginatedSee
GET /products/Product Library (id, name, variant, price, link, photo), filtered by search, paginatedSee
POST /media/Add a picture or video exactly as it is: a public https:// address (url), the file as base64 (data with mimeType), or a multipart fileCreate drafts
POST /media/music/Compose a song, instrumental or sound effect (brief, kind, durationSeconds, style, lyrics)Create content
POST /media/voiceovers/Speak text exactly as written in the workspace's narration voice (direction, speed)Create content
POST /media/motion-graphics/Plan and render a motion graphics video (brief, production)Create content
GET /media/jobs/{id}/Whether music, a voiceover or a motion graphics video is ready, and the finished mediaCreate content
POST /posts/{id}/music/Put a music library track on a post (audioId, confirmed)Create drafts
POST /posts/{id}/media/Put library media on an existing post (mediaIds, mode replace or add, confirmed); an approved post goes back to reviewCreate drafts
GET /analytics/summary/Performance for a dateRange, or startDate and endDateSee
GET /story-series/Your story series (episodic dramas with a fixed cast), paginatedSee
POST /story-series/Create a series (title, premise, style cinematic or animated, episodeSeconds, episodeCount, postWeekdays, postTime, platformAccountIds…)Create drafts
GET /story-series/{id}/One series with its cast, artwork and episodes (episodesPage)See
PATCH /story-series/{id}/Change a seriesCreate drafts
POST /story-series/{id}/characters/Add a character (name, description, mediaIds, voice, draw)Create drafts
DELETE /story-series/{id}/characters/{characterId}/Remove a character (pause a running season first)Create drafts
POST /story-series/{id}/outline/Write the season outline in the backgroundCreate content
POST /story-series/{id}/start/Approve the outline and start; without "confirmed": true it returns the posting times and credits per episodeCreate content
POST /story-series/{id}/pause/, /resume/Pause the season (nothing more is made or posts) or resume it (episodes move to the next slots)Create drafts
POST /story-series/{id}/episodes/{number}/remake/Make a failed or not-yet-posted episode again (cost first, then "confirmed": true)Create content
POST /story-series/{id}/episodes/{number}/post/Post as it is an episode held because its video left out a scripted line (its note says which, held is true)Send and schedule
POST /story-series/{id}/artwork/Draw the key art each episode opens and closes on again (cost first)Create content
POST /generations/Have Asteria write and make posts for platforms: pictures, carousels, videos, motion graphics or songs; productIds (up to 3, from GET /products/) makes the media with those productsCreate content
GET /generations/{id}/Whether a generation has finished, and its postsCreate content
POST /content-plans/previews/Propose a content plan (nothing is saved)Create content
POST /content-plans/Create a plan from a previewIdCreate content
POST /content-plans/drafts/Check a plan you wrote item by item (items, focus): warnings and a draftId, nothing savedCreate content
POST /content-plans/drafts/{draftId}/Create the plan exactly as writtenCreate content
GET /strategy/The content strategy: pillars, sell share, cadence, posting windows, format mix, topics to avoid, experimentsSee
PATCH /strategy/Change the strategy (changes, version, confirmed)Create drafts
GET /platforms/What each platform can publish: formats, media rules, caption and hashtag limitsSee
PATCH /posts/{id}/Change a caption or hashtags (confirmed to apply). An approved or scheduled post goes back to reviewCreate drafts
POST /posts/{id}/visual/Redesign a post's image, carousel or documentCreate content
POST /posts/{id}/archive/Archive a postCreate drafts
POST /posts/{id}/tags/Add or remove a post's tagsCreate drafts
GET /posts/{id}/approvals/Approval history: who, role, channel, time and versionSee
POST /posts/{id}/approval-request/Ask the workspace's approvers (notified in Asteria Engine)Send and schedule
GET /content-plans/ and GET /content-plans/{id}/Plans and their itemsSee
PATCH /content-plans/items/{id}/Change a planned itemCreate content
POST /content-plans/items/{id}/rewrite/Rewrite an item's idea (instruction, then draftId to keep it)Create content
POST /content-plans/items/{id}/lock/Lock or unlock an itemCreate content
POST /content-plans/{id}/generate/Make posts from chosen itemIds, with one credit estimateCreate content
GET /content-plans/production-options/What production can set for videos, motion graphics, songs and picturesSee
GET /videos/options/, POST /videos/previews/, POST /videos/, GET /videos/{id}/, POST /videos/{id}/attach/Authored videos: the script format, check a script and its cost, generate it, check it, and make a draft post from itCreate content
GET /analytics/posts/Each post's results measured at the same age (normaliseDays, default 7), filtered by tagSee
GET /analytics/compare/Two periods side by side, with a breakdown by platform, format or tagSee
GET /analytics/metrics/, GET /analytics/conversions/What each metric means; conversion eventsSee
GET /inbox/, GET /comments/Conversations, and comments still waiting for an answerSee
POST /comments/{id}/reply-drafts/, POST /comments/replies/Draft a reply, then send that exact draftCreate drafts / Send and schedule
GET /leads/Leads without personal detailsSee
GET /meetings/slots/, POST /meetings/Free calendar times; book a meeting with a leadSee / Send and schedule
GET /ads/guardrails/, GET /ads/accounts/, GET /ads/campaigns/, GET /ads/campaigns/{id}/, GET /ads/analytics/, GET /ads/recommendations/Ad limits, accounts, campaigns, results and suggestionsRun ads
POST /ads/campaigns/{id}/pause/, POST /ads/campaigns/{id}/resume/, POST /ads/campaigns/{id}/budget/Pause (straight away), resume, or change a daily budget (raising needs confirmed)Run ads
POST /posts/{id}/submit/Send a post for approvalSend and schedule
POST /posts/{id}/schedule/Schedule an approved post for scheduledForSend and schedule

The full reference, with every field, is published at /api/public/v1/docs/ on the same address, and the machine-readable OpenAPI description at /api/public/v1/schema/.

Plans and the strategy

A plan preview (POST /content-plans/previews/) is built from the workspace's saved strategy. Planning a month can take a few minutes: when the answer has "status": "working", send just its previewId to the same endpoint until it says done. Its interpretation says how the brief was read, and warnings names anything to check, such as a platform with no free posting slots or a format a platform can't publish. To decide every post yourself, send the items to POST /content-plans/drafts/ instead. Dates, platforms and formats are kept exactly as written. The response lists warnings, for example more posts in a week than the strategy's cadence, or a time that clashes with a post already in the calendar.

Each item can also say how it should be made, in production. For a video, the recommended way is your own authored script in production.script (the format from GET /videos/options/): the planned post is made from it exactly as written, scene by scene. Without a script, give durationSeconds and optionally model, aspectRatio and direction, and Asteria Engine's designer plans the scenes at that exact length. Motion graphics items can set the length, look, art style, narration, music, sound effects, captions and presenter. Song items can set the length, style and lyrics. What you set wins over the workspace's defaults. Anything that can't be made, such as a length the platform doesn't accept, is refused with the reason before anything is saved. Anything Asteria Engine decides for you comes back as a warning, for example "Made with omni: the workspace's veo_fast can't make exactly 35 seconds". GET /content-plans/production-options/ lists every setting.

PATCH /strategy/ without confirmed: true only returns the before and after, so you can show it first. Send the version from GET /strategy/ so a change is refused if someone edited the strategy in the meantime. Parts you save this way are kept when Asteria refreshes the strategy automatically.

Launching new ad campaigns isn't available with an API key: starting to spend needs a person, in Asteria Engine or through their AI assistant. Ad spending limits are set only in Asteria Engine.

Generating content spends credits

POST /generations/ first returns the number of credits it would use and, in madeAs, how each post will be made. Send the same request again with "confirmed": true to start. The response has a generation id; check it with GET /generations/{id}/ until it says done. With your own caption, the posts come back straight away instead and their media follows. The finished posts wait for review in the workspace.

contentType can also be video, motion_graphics or song (values are sent as written). Add production to set how the media is made: it takes the same settings as a plan item. For a video, your own authored script in production.script is the recommended way: it is made exactly as written. For a picture (contentType image), production.prompt is sent to the picture model exactly as written, and the picture comes back as it was made, with no text or logo laid over it. It is only fitted to the account's picture shape.

Pagination

Lists take page (from 1) and pageSize (up to 50). The response says which page comes next.

Webhooks

Webhooks tell your systems the moment something happens, so you don't have to keep asking. In Settings › API & Webhooks, select Add endpoint, enter an https:// address and choose the events:

EventSent when
post.waiting_for_reviewA post is waiting for someone to approve it
post.scheduledA post is scheduled
post.publishedA post has been published
post.failedA post could not be published and Asteria Engine has stopped retrying

You get a signing secret (whsec_...) once, when you add the endpoint. Keep it on your server. You can rotate it at any time.

Each event is a POST with a JSON body:

{
  "id": "evt_...",
  "type": "post.published",
  "createdAt": "2026-11-12T09:30:00+00:00",
  "workspace": {"id": 109, "name": "Kirkgate Café"},
  "data": {"post": {"id": 1135, "status": "published", "platform": "instagram", "caption": "...",
                    "scheduledFor": "...", "publishedAt": "...", "platformUrl": "...", "error": null,
                    "openInAsteria": "https://..."}}
}

Check the signature

Every request has an Asteria-Signature header like t=1762939800,v1=5f2c.... To check it, compute an HMAC-SHA256 of the timestamp, a full stop and the raw request body, using your signing secret, and compare it with v1. Reject requests whose timestamp is more than five minutes old.

import hashlib, hmac, time

def is_from_asteria(raw_body: bytes, header: str, secret: str) -> bool:
    parts = dict(item.split("=", 1) for item in header.split(","))
    expected = hmac.new(secret.encode(), f"{parts['t']}.".encode() + raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, parts["v1"]) and abs(time.time() - int(parts["t"])) < 300

Asteria-Event names the event and Asteria-Delivery identifies the delivery. A delivery keeps the same Asteria-Delivery when it is retried, so you can ignore any you have already handled.

Delivery and retries

Answer with any 2xx status within 10 seconds. Otherwise Asteria Engine tries again after 1 minute, 5 minutes, 30 minutes, 2 hours and 6 hours. If five events in a row can't be delivered, the endpoint is turned off and the reason is shown in Settings; turn it back on once it is fixed. Send test sends a webhook.test event straight away, and Recent deliveries shows the last 30 days.

Webhooks are only sent to public addresses, and redirects are not followed.

Errors

Errors have the same shape everywhere:

{"error": {"message": "What went wrong, in plain words", "code": "missing_scope"}}
StatusMeaning
400Something in the request needs fixing; the message says what
401No key, or the key is wrong, revoked or expired
403The key isn't allowed to do this (missingScopes lists what it lacks), or the workspace's plan no longer includes the API
429More than 60 requests a minute with this key; wait and try again (see Retry-After)

Activity and security

Every request made with a key is recorded in the workspace's activity, with the key that made it. Keys are stored only as a one-way hash, so nobody, including Asteria Engine staff, can read a key after it is created.

Keep keys out of browser code and public repositories. If a key may have leaked, revoke it in Settings › API & Webhooks; it stops working immediately.

Put the guide into practice

Build the workflow in a live Asteria Engine workspace.

Connect your channels, add brand context, and turn the setup steps in this guide into draftable, schedulable content.

Need Help?

If you have questions or run into issues, our support team is here to help.