Errors
Every failure answers with the same envelope and a stable machine code.
{
"success": false,
"errors": [
{
"code": "quota_exceeded",
"message": "The plan quota for this action is used up.",
"retryable": false,
"details": { "slideshows_remaining": 0 }
}
]
}
Branch on code. Messages are written for people and may be reworded; codes are the contract. retryable says whether sending the same request again could ever work: false means fix something first, true means the failure was about timing or load.
details appears when there is something concrete to hand back, such as required_scope on a permission failure, fields on a validation failure or retry_after_seconds on a rate limit.
Two ways to look a code up at runtime, so an agent never has to guess:
curl https://reel.money/api/v1/errors/quota_exceeded \
-H "Authorization: Bearer rm_your_key"
Over MCP, the same lookup is the explain_error tool.
HTTP status, in short
| Status | Means |
|---|---|
| 400 | The request could not be read. |
| 401 | No key, or a key that is not valid, revoked or expired. |
| 402 | Not enough credits. |
| 403 | The key lacks a scope, or the plan quota is used up. |
| 404 | No such record, or not one this key can see. |
| 409 | The record is busy or has moved past the point where this action applies. |
| 415 | That file type is not supported. |
| 422 | The body did not pass validation, or a platform rule blocks it. |
| 429 | Too many requests, from this key or towards a social platform. |
| 5xx | Our side. Try again in a moment. |
Every code
This table is generated from the same catalog the API answers with, so it is never out of step with what you will actually receive.
| Code | Message | Cause | Fix | Retry helps |
|---|---|---|---|---|
missing_token | No API key was sent with the request. | The Authorization header was missing or did not contain a bearer token. | Send the header Authorization: Bearer rm_your_key with every request. | no |
invalid_token | The API key is not valid. | No active key matches the token that was sent. | Check the key was copied in full, then create a new key in ReelMoney under Settings and API keys. | no |
key_revoked | This API key was revoked. | Someone revoked the key in the ReelMoney dashboard. | Create a new key in ReelMoney under Settings and API keys, then use that token. | no |
key_expired | This API key has expired. | The key passed the expiry date chosen when it was created. | Create a new key in ReelMoney under Settings and API keys, then use that token. | no |
missing_scope | The API key does not have the permission this endpoint requires. | The key was created without the scope listed in details.required_scope. | Edit the key in ReelMoney and tick the missing permission, or create a new key with it. | no |
approval_required | This action needs a person to approve it first. | The action is gated behind human approval. | Ask the account owner to approve the action, then send the request again. | no |
quota_exceeded | The plan quota for this action is used up. | The account reached its limit for the current billing period or the free tier limit. | Wait for the quota to reset, or upgrade the plan. Call GET /api/v1/account to see what is left. | no |
insufficient_credits | The account does not have enough credits for this action. | AI image generation and some renders spend credits, and the balance is too low. | Buy credits in ReelMoney, or choose an image source of pack or stock instead of ai. | no |
validation_failed | The request body did not pass validation. | One or more fields are missing or hold a value the endpoint does not accept. | Read details.fields for the exact problems, correct the body and send the request again. | no |
bad_request | The request could not be read. | A required parameter was missing, or the body was not valid JSON. | Check the endpoint reference in the OpenAPI document, then send a corrected request. | no |
not_found | That record does not exist, or this key cannot see it. | The id belongs to another brand, or the record was deleted. | List the records first and use an id from that response. | no |
unknown_error_code | That error code is not in the catalog. | GET /api/v1/errors/:code was called with a code ReelMoney does not publish. | Read details.known_codes for the full list, then look up one of those codes. | no |
job_not_found | That job does not exist for this brand. | The job id was wrong, or the job belongs to another brand. | Use the job id returned by the create call that started the work. | no |
conflict | The record is in a state that does not allow this action. | Work is already running on it, or it has moved past the point where this action applies. | Poll the job or the record until it settles, then decide what to do. | yes |
job_in_progress | A job is still running on this record. | The record is being generated or rendered right now, so it cannot be changed. | Poll GET /api/v1/jobs/:id until the job settles, then send the request again. | yes |
generation_failed | The generation job failed. | The job hit an error while generating this content. | Read the error message, adjust the request if needed and start a new generation. | yes |
idempotency_conflict | This Idempotency-Key was already used with a different request body. | An Idempotency-Key may only ever be paired with one request body. | Send the original body again to replay the stored response, or use a fresh Idempotency-Key. | no |
media_too_large | The file is larger than the limit for its type. | Images may be up to 10 MB and videos up to 200 MB. | Compress the file or shorten the video, then upload it again. | no |
unsupported_media_type | That file type is not supported. | The content type is outside the allowed list for images and videos. | Convert the file to jpeg, png, webp or mp4 and upload it again. | no |
platform_not_connected | No connected account was found for that platform. | The brand has never connected the platform, or the connection was removed. | Call POST /api/v1/connections/link, open the returned URL in a browser and finish the connect flow. | no |
token_expired | The connection to that platform has expired. | The platform access token expired or was revoked by the platform. | Reconnect the account with POST /api/v1/connections/link and open the returned URL. | no |
platform_rate_limited | The social platform is refusing more posts right now. | The platform posting cap for this account was reached. TikTok allows 15 posts per 24 hours. | Schedule the post for later, or post to another connected account. | yes |
unsupported_platform | That platform is not one ReelMoney posts to. | The platform name was not tiktok, youtube, instagram or linkedin. | Send one of tiktok, youtube, instagram or linkedin. Call GET /api/v1/capabilities for the list. | no |
platform_not_configured | This ReelMoney server cannot start a connect flow for that platform. | The client id or the callback URL for the platform is missing from the server settings. | Connect the account from the ReelMoney dashboard instead, and tell support the platform is unset. | no |
short_not_postable | That short has nothing to publish yet. | The short has no rendered video and no slides, so there is no file to send to a platform. | Poll GET /api/v1/jobs/:id until the short succeeds, then post it. | yes |
caption_too_long | The caption is longer than the platform accepts. | Each platform caps caption length. TikTok allows 4000 characters and Instagram allows 2200. | Shorten the caption, or send a shorter one for this account in platform_customizations. | no |
title_too_long | The title is longer than the platform accepts. | Each platform caps title length. TikTok allows 90 characters and YouTube allows 100. | Shorten the title, or send a shorter one for this account in platform_customizations. | no |
schedule_too_soon | That scheduled time is in the past or too close to now. | A scheduled post needs at least 5 minutes of lead time so the job can be queued. | Send scheduled_at as an ISO 8601 time at least 5 minutes ahead, or omit it to post right away. | no |
not_cancellable | That post can no longer be cancelled. | Only posts still sitting in draft, pending or scheduled can be pulled back. | Read the post status with GET /api/v1/posts and cancel only the ones that have not gone out. | no |
rate_limited | This API key sent too many requests. | The key passed one of the request ceilings for the current window. | Wait for details.retry_after_seconds, then send the request again. Spread bursts over time. | yes |
internal_error | Something went wrong on our side. | The request reached ReelMoney but could not be completed. | Send the request again in a moment. If it keeps failing, contact support with the request id. | yes |
Handling them well
- **
quota_exceededandinsufficient_creditsare not retry material.** CallGET /api/v1/accountbefore a run and stop early rather than failing halfway. - **
missing_scopeis a message for a person.** Relaydetails.required_scopeand the fix text: someone has to tick a box on the key. - **
rate_limitedcarriesRetry-After.** Honour it. Retrying sooner just spends the next window. - **
platform_rate_limitedis the platform's cap, not ours.** Schedule the post for later or send it to another account. - **
token_expiredandplatform_not_connectedboth end at the same place:** build a connect link withPOST /api/v1/connections/linkand give it to a person. - **
job_in_progressandconflictmean wait, then look again.** Poll the job rather than retrying the edit in a tight loop. - **
idempotency_conflictmeans the key was reused.** Send the original body to replay the first answer, or use a fresh key for a genuinely new request.
Reading this as an agent? Every page is also plain markdown: /api-docs/errors.md