AI API
The AI endpoints write captions for several platforms in one call and suggest hashtags. AI runs on your own provider key (bring your own key). There is no shared key, so until a workspace adds one, generation returns 503.
All routes are under /api/ai and need the ai.use permission, which every role has. The whole controller is limited to 10 requests per minute. Auth is in the REST API overview.
Which AI endpoints can I call?
| Method | Path | Purpose | Permission | Guarded API key |
|---|---|---|---|---|
GET | /ai/status | Is AI available? | ai.use | Yes |
POST | /ai/generate-content | Captions per platform | ai.use | Yes |
POST | /ai/suggest-hashtags | Hashtag suggestions | ai.use | Yes |
GET | /ai/settings | Read provider and model | ai.use | No |
PUT | /ai/settings | Save your provider key | workspace.edit | No |
DELETE | /ai/settings | Remove your key | workspace.edit | No |
How do I check that AI is set up?
curl https://api.socifyr.com/api/ai/status \
-H "Authorization: Bearer sk_..."{ "success": true, "data": { "available": true, "source": "byok", "model": "gemini-2.5-flash" } }Without a key: { "available": false, "source": null, "model": "<default model>" }.
How do I generate captions for several platforms?
POST /ai/generate-content returns one caption per platform, sized to each platform's character limit and style.
| Field | Type | Required | Constraints |
|---|---|---|---|
uploadType | enum | Yes | video, photo, text, document |
platforms | string[] | Yes | Non-empty. Platform names from SUPPORTED_PLATFORMS, for example instagram, x, linkedin. These are platform types, not connection slugs. |
text | string | No | Draft to refine. Max 5 000. |
title | string | No | Context. Max 5 000. |
description | string | No | Context. Max 5 000. |
tone | enum | No | professional, casual, humorous, inspirational, informative |
brandVoice | string | No | Free text such as Friendly startup, no jargon. Max 1 000. |
curl -X POST https://api.socifyr.com/api/ai/generate-content \
-H "Authorization: Bearer sk_..." \
-H "Content-Type: application/json" \
-d '{
"uploadType": "text",
"platforms": ["linkedin", "x"],
"text": "We added bulk scheduling from CSV.",
"tone": "professional",
"brandVoice": "Plain, specific, no hype"
}'{
"success": true,
"data": {
"content": {
"linkedin": "Bulk scheduling from CSV is live. Upload one file and plan a month of posts in a single step.",
"x": "Bulk scheduling from CSV is live. Plan a month of posts with one upload."
}
}
}The text is generated by your model, so your output will differ. Use the result as the text of POST /content/text.
How do I get hashtag suggestions?
POST /ai/suggest-hashtags
| Field | Type | Required | Constraints |
|---|---|---|---|
text | string | Yes | Max 5 000 |
platforms | string[] | Yes | Non-empty, platform names |
count | integer | No | 1 to 30, default 10 |
existingHashtags | string[] | No | Tags already in the post. The model reviews them and proposes replacements. |
curl -X POST https://api.socifyr.com/api/ai/suggest-hashtags \
-H "Authorization: Bearer sk_..." \
-H "Content-Type: application/json" \
-d '{ "text": "Bulk scheduling from CSV", "platforms": ["instagram"], "count": 5 }'{
"success": true,
"data": {
"hashtags": [
{ "tag": "socialmediatools", "score": 88 },
{ "tag": "contentcalendar", "score": 81 }
]
}
}tag has no leading #. score is a relevance number from 0 to 100 given by the model.
How do I add my own AI key?
PUT /ai/settings validates the key with a small live call before saving it. It stores the key encrypted and never returns it.
| Field | Type | Required | Constraints |
|---|---|---|---|
apiKey | string | Yes | 10 to 400 characters |
provider | string | No | One of openai, anthropic, google, mistral, xai. Defaults to google. |
model | string | No | Max 100 characters. Defaults to the provider's default model. |
curl -X PUT https://api.socifyr.com/api/ai/settings \
-H "Authorization: Bearer <session-token-or-unrestricted-key>" \
-H "Content-Type: application/json" \
-d '{ "provider": "anthropic", "apiKey": "sk-ant-..." }'{ "success": true, "data": { "success": true } }GET /ai/settings returns { "provider": "anthropic", "model": null, "hasKey": true }. DELETE /ai/settings removes the key and returns { "success": true }.
What errors can the AI endpoints return?
| Status | Cause | Fix |
|---|---|---|
| 503 | No AI provider key set for this workspace. Add your own key in Settings → AI to use AI features. | Add a key with PUT /ai/settings or in the dashboard. |
| 400 | That API key could not be validated with the provider... | Check the key, the provider, and the model name. |
| 400 | Validation, such as an empty platforms array or an unknown tone | Fix the body. |
| 429 | More than 10 AI requests in a minute | Wait and retry. |
Frequently asked questions
Does Socifyr charge for AI usage? Calls run against your own provider account, so your provider bills you.
Can an agent change the AI key? No. Settings routes are blocked for guarded keys. Agents can generate, not reconfigure.