API keys and guardrails API
API keys authenticate scripts, SDKs, the CLI and MCP agents. Each key belongs to one workspace. A key can carry guardrails that cap what an automated client can do. This page covers the key endpoints and exactly which routes a guarded key may call.
Key management routes live under /api/workspaces/:id/api-keys. For how to send a key, see API keys.
Which API key endpoints can I call?
| Method | Path | Purpose | Permission |
|---|---|---|---|
GET | /workspaces/:id/api-keys | List keys | api_key.view |
POST | /workspaces/:id/api-keys | Create a key | api_key.create |
PUT | /workspaces/:id/api-keys/:keyId | Update label and guardrails | api_key.update |
DELETE | /workspaces/:id/api-keys/:keyId | Delete a key | api_key.delete |
A key that has any guardrail cannot call any of these four routes, so an agent cannot lift its own limits or create an unrestricted key. Change guardrails from the dashboard or with an unrestricted key.
How do I create an API key?
POST /workspaces/:id/api-keys
| Field | Type | Required | Constraints |
|---|---|---|---|
label | string | Yes | 1 to 60 characters |
curl -X POST https://api.socifyr.com/api/workspaces/6a04f0000000000000000001/api-keys \
-H "Authorization: Bearer <session-token-or-unrestricted-key>" \
-H "X-Workspace-Id: 6a04f0000000000000000001" \
-H "Content-Type: application/json" \
-d '{ "label": "Content agent" }'{
"success": true,
"data": {
"key": "sk_...full key, shown once...",
"prefix": "sk_4b7378404",
"id": "c51b393e-40d1-481e-94c3-042726c44ad1",
"message": "Copy this key now — it will not be shown again."
}
}Store key immediately. It cannot be retrieved again. The number of keys depends on the plan. See Limits.
| Status | Cause | Fix |
|---|---|---|
| 400 | label missing or longer than 60 characters | Fix the body. |
| 403 | Your plan allows a maximum of N API key(s). Upgrade to create more. | Delete an old key or upgrade. |
| 403 | This API key has guardrails and cannot manage API keys... | Use a dashboard session or an unrestricted key. |
| 403 | Your role does not have the 'api_key.create' permission | Ask an Owner or Admin. |
How do I list API keys?
curl https://api.socifyr.com/api/workspaces/6a04f0000000000000000001/api-keys \
-H "Authorization: Bearer <session-token-or-unrestricted-key>"{
"success": true,
"data": [
{
"id": "c51b393e-40d1-481e-94c3-042726c44ad1",
"prefix": "sk_4b7378404",
"label": "Content agent",
"createdAt": "2026-11-01T10:00:00.000Z",
"lastUsedAt": "2026-11-13T08:55:00.000Z",
"dailyPostLimit": 20,
"monthlyXSpendCentsCap": 500,
"requireApproval": true,
"xSpendCents": 35,
"xSpendMonth": "2026-11"
}
]
}The raw key is never returned, only its prefix. xSpendCents is the X spend recorded this month through this key.
What guardrails can an API key have?
Set them with PUT /workspaces/:id/api-keys/:keyId. Send only the fields you want to change. Send null to remove a limit.
| Field | Type | Constraints | Effect |
|---|---|---|---|
label | string | 1 to 60 characters | Rename the key. |
dailyPostLimit | integer or null | At least 1 | Max posts per UTC day through this key. |
monthlyXSpendCentsCap | integer or null | At least 0 | Max X (Twitter) spend per month through this key, in US cents. |
requireApproval | boolean | Every post the key creates goes to pending_approval and needs a human to approve it. |
curl -X PUT https://api.socifyr.com/api/workspaces/6a04f0000000000000000001/api-keys/c51b393e-40d1-481e-94c3-042726c44ad1 \
-H "Authorization: Bearer <session-token-or-unrestricted-key>" \
-H "X-Workspace-Id: 6a04f0000000000000000001" \
-H "Content-Type: application/json" \
-d '{ "dailyPostLimit": 20, "monthlyXSpendCentsCap": 500, "requireApproval": true }'{ "success": true, "data": { "success": true, "id": "c51b393e-40d1-481e-94c3-042726c44ad1" } }A key with any one of these set is a guarded key. Errors: 400 for invalid values, 404 Workspace or API key not found.
What do I see when a guardrail blocks a request?
| Guardrail | Response |
|---|---|
| Daily limit | 403 API key "<label>" reached its daily post limit (N/day). The limit resets at 00:00 UTC — raise it in the dashboard if agents need more throughput. |
| X spend cap | 403 X (Twitter) spend cap reached for API key "<label>" ($N/month). Posts to X through this key are blocked until the monthly reset or until an admin raises the cap. |
| Require approval | Create calls succeed with status: "pending_approval". Publish, approve and reject return 403 This API key requires approval and cannot .... |
| Route not allowed | 403 This API key has guardrails and cannot call this endpoint — use a dashboard session or an unrestricted key |
| Someone else's post | 403 This API key has guardrails and can only modify posts it created itself |
| Editing a non-draft | 403 This API key has guardrails and can only edit drafts — this post is "<status>" |
Which endpoints can a guarded API key call?
Guardrails are deny-by-default. A guarded key may call only these routes. Every other route returns 403.
| Area | Allowed routes |
|---|---|
| Account | GET /users/me, GET /usage |
| Workspaces | GET /workspaces, GET /workspaces/:id, GET /workspaces/:id/connections |
| Content | POST /content/text, /content/photos, /content/video, /content/document, GET /content, GET /content/status, GET /content/:id, PATCH /content/:id (drafts only), POST /content/bulk-schedule, POST /content/:id/publish, /publish-now (not with require-approval), POST /content/:id/retry, POST /content/:id/submit-for-approval, PATCH /content/:id/archive, /unarchive, DELETE /content/:id |
| Media | POST /media/upload, GET /media, GET /media/:id |
| Analytics | All GET /analytics* routes and POST /analytics/sync |
| AI | GET /ai/status, POST /ai/generate-content, POST /ai/suggest-hashtags |
For modify routes (PATCH, publish, retry, archive, delete, submit-for-approval), a guarded key can only act on posts that key created.
Not allowed for a guarded key: refreshing or reconnecting connections, approve and reject, bulk delete and bulk archive, webhooks, members, invitations, API key management, billing, AI settings, and media edit and delete.
How do I delete an API key?
curl -X DELETE https://api.socifyr.com/api/workspaces/6a04f0000000000000000001/api-keys/c51b393e-40d1-481e-94c3-042726c44ad1 \
-H "Authorization: Bearer <session-token-or-unrestricted-key>" \
-H "X-Workspace-Id: 6a04f0000000000000000001"Returns 204 with no body. Requests using the key fail with 401 Invalid API key afterwards. 404 Workspace or API key not found if the ID is wrong.
Frequently asked questions
Which guardrails should I give an AI agent? Turn on require-approval first, so a person reviews every post. Add a daily post limit as a second line, and an X spend cap if the agent posts to X. See the approvals guide.
Does a guarded key count toward my plan's key limit? Yes. Every key counts.