Api Ai
AI and prompts
The choice to make first
| Route | Cost | Needs an AI key? | Scope |
|---|---|---|---|
GET /ai/prompts/suggestions/ |
free | no | read |
POST /ai/prompts/rewrite/ |
free | no | read |
POST /ai/suggestions/ |
one provider call | yes | write |
POST /ai/rewrite/ |
one provider call | yes | write |
The prompt routes return exactly what we would have sent to the model, with your real posts already interpolated. If the caller is itself an AI agent, it should run that prompt and skip the paid route entirely.
GET /ai/prompts/suggestions/
Optional ?topic=shipping in public to steer it.
{"status": "success", "data": {
"handle": "alice.bsky.social",
"post_count": 128,
"system": "...",
"prompt": "...",
"combined": "..."
}}
Use system and prompt separately, or combined if you have one input box.
The prompt asks for a single JSON object containing post_suggestions (a list
of strings) plus seven analysis keys.
POST /ai/prompts/rewrite/
{"text": "my rambling draft", "instructions": "punchier, under 300 characters"}
Returns the same system / prompt / combined trio.
POST /ai/suggestions/
Spends one call on your own key. Optional body {"topic": "..."}.
{"status": "success", "data": {
"handle": "alice.bsky.social",
"posts_analyzed": 128,
"suggestions": ["...", "..."],
"insights": {"tone_style": {"...": "..."}}
}}
With no post history it returns an empty list and a message telling you to sync first, rather than an error.
GET /ai/suggestions/ and DELETE /ai/suggestions/{id}/
Listing stored suggestions is free and works with a read key. Deleting needs write scope, and only ever touches your own account's suggestions.
POST /ai/rewrite/
{"text": "my rambling draft", "instructions": "punchier"}
Returns {"text": "...", "original": "..."}.
This is POST, not GET, on purpose. The internal endpoint the web app uses puts draft text in the query string, which means post content lands in access logs. The public API does not repeat that.
When there is no AI key
Both paid routes return 403 no_ai_key with a prompt_url pointing at the free
equivalent, rather than dead-ending. Any agent worth using should follow it.