Skip to content

Responses and errors

Every action answers the same way on REST, MCP and the CLI.

{
"ok": true,
"summary": "Scheduled for Tue 28 Oct, 10:00 (America/New_York) on @yourhandle.",
"data": {
"postId": "…",
"scheduledAt": "2026-10-28T14:00:00.000Z"
},
"ids": {
"postId": "…"
}
}
Field Meaning
summary One or two readable sentences. Read it first; models can relay it as is.
data The result. Its shape depends on the action.
ids IDs worth acting on next, such as postId.
next Suggested next calls, by MCP tool name.
creditsCharged AI credits actually spent, when any.
dryRun true when nothing was changed because you passed dryRun.
{
"ok": false,
"error": {
"code": "SCOPE_MISSING",
"message": "This connection isn't allowed to post, send and change what goes out on X yet. Give the user this link to allow it (one click in Xholic), then try again: https://app.xholic.ai/oauth/allow?connection=…&scope=publish",
"scope": "account",
"details": {
"missingScope": "publish",
"allowUrl": "https://app.xholic.ai/oauth/allow?connection=…&scope=publish"
}
}
}

code is stable; branch on it, not on the message. scope says whose problem it is: account means something you or the account can fix, platform means Xholic or X is having trouble and a retry later should work. retryAfterSeconds is set when waiting helps, and details carries more (validation issues, a credit quote).

On MCP the same object comes back as a tool result with isError: true, and the text starts with CODE: message.

Code HTTP Scope Meaning
UNAUTHENTICATED 401 account No credential was sent, or the action needs an account.
INVALID_CREDENTIAL 401 account The API key or token is wrong, revoked or expired.
SCOPE_MISSING 403 account The connection lacks the write or publish scope this action needs. details.allowUrl lets the person allow it in one click.
ROLE_NOT_PERMITTED 403 account Your role on a shared account doesn’t allow this action.
ACCOUNT_NOT_FOUND 404 account The account isn’t one this login can use.
SUBSCRIPTION_REQUIRED 402 account The subscription isn’t active. Keys and connections are kept.
FEATURE_NOT_INCLUDED 403 account The plan doesn’t include this feature.
APP_ONLY 403 account This change can only be made in the Xholic app.
INVALID_INPUT 400 account The input failed validation; details lists each field.
NOT_FOUND 404 account The thing you referenced doesn’t exist, or the endpoint doesn’t.
CONFLICT 409 account The change clashes with the current state (for example an old article version).
CREDITS_CONFIRMATION_REQUIRED 402 account The action uses Xholic AI. details.quote has the estimate and a quoteId; call again with confirmCredits and quoteId.
INSUFFICIENT_CREDITS 402 account Not enough AI credits left for this action.
RATE_LIMITED 429 account Too many requests in this bucket. Wait retryAfterSeconds.
IDEMPOTENCY_KEY_REUSED 409 account The key was already used for a different request.
IDEMPOTENCY_IN_PROGRESS 409 account A request with this key is still running. Retry with the same key shortly.
X_DATA_LIMIT_REACHED 429 account The plan’s live X data allowance is used up for now.
UPSTREAM_UNAVAILABLE 503 platform X or another service Xholic depends on is unavailable. Retry later.
INTERNAL_ERROR 500 platform Something failed on Xholic’s side. Retry later.

Every surface adds these to an action’s own input:

Field Type Applies to What it does
account string Every action that acts on an X account X account to act on, as @handle. Leave it out to use the connection’s default account.
dryRun boolean Every change Return exactly what would happen without doing it.
idempotencyKey string Every change (required on publish_now) A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice.
confirmCredits number Actions that use Xholic AI Xholic AI credits the user agreed to spend. Call first without it to get the quote, show the quote to the user, and pass the amount only after they say yes.
quoteId string Actions that use Xholic AI The quoteId from the quote the user agreed to. Send it with confirmCredits.
Header Meaning
X-RateLimit-Limit Requests allowed per minute in this action’s bucket.
X-RateLimit-Remaining Requests left this minute.
X-RateLimit-Reset Seconds until the bucket refills.
X-Xholic-Credits-Remaining AI credits left, on actions that quote credits.
Retry-After Seconds to wait, on 429 and some 409/503 errors.

Responses are Cache-Control: no-store. The API takes bearer credentials only and never reads cookies.