> ## Documentation Index
> Fetch the complete documentation index at: https://www.ayrshare.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Ayrshare Error Codes

> Ayrshare specific returned error codes.

The REST API will include a response with a list of errors if applicable.

<Info>
  Errors have a returned status code of 400, 401, 402, 403, 404, 429, 500, 502, 503, or 504. Success has a returned
  status code 200. See [here](/errors/errors-http) for details.
</Info>

Each API call can return different errors depending on the specific request and any issues encountered at the social network.
The error response will contain details about what went wrong during the API call.

For example, a post that is considered a duplicate by Twitter and Facebook would return the following response.

```json theme={"system"}
{
  "status": "error",
  "errors": [
    {
      "action": "post",
      "status": "error",
      "code": 110,
      "message": "Status is a duplicate.",
      "post": "Today is a great day",
      "platform": "twitter"
    },
    {
      "action": "post",
      "status": "error",
      "code": 107,
      "message": "Facebook Error: This status update is identical to the last one you posted.
        Try posting something different, or delete your previous update.",
      "platform": "facebook"
    }
  ],
  "postIds": [],
  "id": "6APU4qqI7XO7JM3BOy6B"
}
```

Please note:

<ul class="custom-bullets">
  <li>
    The `errors` field contains the array of errors, one per social network that had an error.
  </li>

  <li>The `action` refers to the type of error returned.</li>

  <li>
    The top-level `status` field will be "error" if the API call failed. For example, for a /post
    call if all social network posting were successful the `status` field will be "success", else
    the status field will be "error".
  </li>

  <li>The `code` field contains the Ayrshare reference error code.</li>
  <li>The `message` field is the specific details of the error.</li>
</ul>

### Handling Errors

You should handle any error responses and take the appropriate action. An error occurred if:

<ul class="custom-bullets">
  <li>The response return code is not `200`</li>
  <li>The JSON response status is `error`</li>
</ul>

For example, if Facebook link was removed by your user - they changed their password or removed Ayrshare's access - the following response would occur when posting with a `400 Bad Request` response code.

```json theme={"system"}
{
  "status": "error",
  "errors": [
    {
      "action": "post",
      "status": "error",
      "code": 161,
      "message": "Facebook authorization error. This can occur if your Facebook security changes. Try unlinking and re-linking Facebook or contact us for assistance.",
      "platform": "facebook"
    }
  ],
  "postIds": [],
  "id": "gh7SyTpeD2CQAMxWk3oh",
  "post": "A great Facebook Posts"
}
```

An action might be to notify your user via your dashboard, text or email.

Another example is if the posted Instagram image is the wrong dimensions or ratio with a `400 Bad Request` response code:

```json theme={"system"}
{
  "status": "error",
  "errors": [
    {
      "action": "post",
      "status": "error",
      "code": 138,
      "message": "Instagram Error: There was an issue posting to Instagram. The submitted image with aspect ratio ('1440/2158',) cannot be published. Please submit an image with a valid aspect ratio.",
      "platform": "instagram"
    }
  ],
  "postIds": [],
  "id": "Jxe2nMM3FmEvMXFSY3g4",
  "post": "Is this a good image?"
}
```

An action might be resending the images with the correct ratio.

### Instagram-Specific Error Codes

The following error codes provide specific details about Instagram posting failures, replacing the generic error 138 where possible.

**Code 435 — Instagram Rate Limit (HTTP 429)**

Instagram professional (Business / Creator) accounts are subject to a 50-post rolling 24-hour limit on Meta's [Content Publishing API](https://developers.facebook.com/docs/instagram-platform/instagram-graph-api/reference/ig-user/content_publishing_limit/) (personal accounts cannot publish via API at all and therefore never hit this limit). When the cap is exceeded, Meta returns a rate-limit error. Ayrshare also surfaces `code: 435` when Meta's publish endpoint returns HTTP 429 directly or when the underlying error subcode (`1390008`) indicates a post / comment throttle.

```json theme={"system"}
{
  "status": "error",
  "errors": [
    {
      "action": "rate limit",
      "status": "error",
      "code": 435,
      "message": "Instagram rate limit reached. Please wait before retrying your post.",
      "details": "Retry-After: 3600",
      "platform": "instagram"
    }
  ]
}
```

**Action:** Wait for the rate limit window to reset before retrying. When Meta supplies a `Retry-After` header, the value (in seconds) is passed through on the `details` field — wait at least that long before resubmitting.

**Code 436 — Instagram Media Processing Timeout (HTTP 400)**

Instagram took too long to process the uploaded media. This can happen with large video files or during periods of high load on Meta's servers.

```json theme={"system"}
{
  "status": "error",
  "errors": [
    {
      "action": "post",
      "status": "error",
      "code": 436,
      "message": "Instagram media processing timed out. Please try posting again.",
      "retryAvailable": true,
      "platform": "instagram"
    }
  ]
}
```

**Action:** Retry the post using the [retry post](/apis/post/retry-post) endpoint. If the issue persists, try reducing the media file size.

**Code 447 — Instagram Trial Reels: Missing graduationStrategy (HTTP 400)**

Returned when `instagramOptions.trialParams` is provided on a [`/post`](/apis/post/post) request but `graduationStrategy` is missing, `null`, or an empty string. Trial reels require an explicit graduation strategy — see [Trial Reels](/apis/post/social-networks/instagram#trial-reels).

```json theme={"system"}
{
  "status": "error",
  "errors": [
    {
      "action": "post",
      "status": "error",
      "code": 447,
      "message": "Instagram trial reels require instagramOptions.trialParams.graduationStrategy (\"MANUAL\" or \"SS_PERFORMANCE\").",
      "platform": "instagram"
    }
  ]
}
```

**Action:** Set `instagramOptions.trialParams.graduationStrategy` to either `"MANUAL"` or `"SS_PERFORMANCE"` and retry, or remove `trialParams` if you did not intend to publish a trial reel.

**Code 448 — Instagram Trial Reels: Invalid graduationStrategy (HTTP 400)**

Returned when `graduationStrategy` is present but is not exactly `"MANUAL"` or `"SS_PERFORMANCE"`. The check is case-sensitive — values like `"manual"` or `"ss_performance"` are rejected. The `details` field echoes the rejected input (truncated to 64 characters) to aid debugging.

```json theme={"system"}
{
  "status": "error",
  "errors": [
    {
      "action": "post",
      "status": "error",
      "code": 448,
      "message": "Invalid Instagram graduationStrategy. Must be \"MANUAL\" or \"SS_PERFORMANCE\".",
      "details": "Received: manual",
      "platform": "instagram"
    }
  ]
}
```

**Action:** Send `graduationStrategy` as exactly `"MANUAL"` or `"SS_PERFORMANCE"` (uppercase, string type).

**Code 449 — Instagram Trial Reels: Incompatible Media (HTTP 400)**

Returned when the media or post shape is not eligible for a trial reel. Trial reels must be a single `.mp4` or `.mov` video — carousels (more than one URL), stories (`instagramOptions.stories: true`), and non-video extensions are all rejected. The `details` field disambiguates which sub-case fired.

```json theme={"system"}
{
  "status": "error",
  "errors": [
    {
      "action": "post",
      "status": "error",
      "code": 449,
      "message": "Instagram trial reels must be a single video (.mp4 or .mov) — carousels and stories are not supported.",
      "details": "Carousels are not supported.",
      "platform": "instagram"
    }
  ]
}
```

**Action:** Submit a single `.mp4` or `.mov` video URL with no `stories: true` flag. Drop additional `mediaUrls` entries, or remove `trialParams` if you intended a regular carousel/story post.

**Code 258 — Instagram Account-State Error (HTTP 400)**

A general Instagram account-state failure with the base message "Error with Instagram." This surfaces when Meta rejects the request due to the state of the connected Instagram account rather than the content of the post.

```json theme={"system"}
{
  "status": "error",
  "errors": [
    {
      "action": "post",
      "status": "error",
      "code": 258,
      "message": "Error with Instagram.",
      "platform": "instagram"
    }
  ]
}
```

When the underlying Meta `error_subcode` is `2207085`, the response additionally sets `relink: true` and `retryAvailable: true`, and the message instructs the user to unlink and relink the Instagram account, granting all permissions:

```json theme={"system"}
{
  "status": "error",
  "errors": [
    {
      "action": "post",
      "status": "error",
      "code": 258,
      "message": "Error with Instagram. Please unlink and relink your Instagram account, granting all permissions, then retry.",
      "relink": true,
      "retryAvailable": true,
      "platform": "instagram"
    }
  ]
}
```

**Action:** For the `2207085` sub-case, prompt the user to unlink and relink their Instagram account in [Social Accounts](https://app.ayrshare.com/social-accounts), granting all requested permissions, then retry the post. For other account-state errors, verify the Instagram account is in good standing on Meta and retry.

#### Retry Available

Sometimes the social networks have a unrecoverable error, such as their are having server issues, and the call ultimately fails even after numerous retries.
In those cases, our system will determine if the error is retryable and if so, the `retryAvailable` field will be `true`.

```json theme={"system"}
{
  "retryAvailable": true
}
```

You can then retry the call with the same payload.
If it is a post you can use the [retry post](/apis/post/retry-post) endpoint.

### X/Twitter BYO Key Errors

The following error codes are specific to X/Twitter BYO (Bring Your Own) key operations:

**Code 272 - Failed to Verify BYO Twitter Identity (HTTP 400)**

Ayrshare could not confirm your X/Twitter identity using your BYO consumer keys and the OAuth tokens stored at link time. The response shape varies by which call triggered it; both forms map to the same three sub-cases below. Verify which one applies by logging into [x.com](https://x.com) with the account that owns the BYO Developer App.

The post path emits a minimal response:

```json theme={"system"}
{
  "status": "error",
  "code": 272,
  "message": "Failed to verify BYO Twitter identity",
  "platform": "twitter"
}
```

The analytics path emits a longer, self-documenting message and may include a `details` field carrying X's raw error string:

```json theme={"system"}
{
  "action": "post",
  "status": "error",
  "code": 272,
  "message": "There is an issue authorizing your X/Twitter account. Login to x.com to verify your account status and then try unlinking Twitter and relinking on the social accounts page.",
  "resolution": {
    "relink": true,
    "platform": "twitter"
  },
  "details": "The user used for authentication is suspended"
}
```

When present, `details` mirrors the X-side hint and is the most reliable single signal for which sub-case below applies.

**Account suspended.** Logging into x.com shows a suspension notice. **Action:** Contact X support. Re-linking will not restore access until X reinstates the account.

**Account locked.** Logging into x.com presents an unlock challenge (CAPTCHA, phone verification, etc.). **Action:** Complete the unlock challenge on x.com, then retry the request. No re-link is required.

**Identity or key mismatch.** Your X account is in good standing on x.com, but your BYO consumer keys belong to a different X Developer App than the OAuth tokens stored at link time. **Action:** Re-link X under Social Accounts and authorize with the same X account that owns the BYO Developer App.

**Code 416 — X Credits Depleted (HTTP 402)**

Your X Developer account has no API credits loaded. All X API calls require credits.

```json theme={"system"}
{
  "status": "error",
  "code": 416,
  "message": "Your enrolled account does not have any credits to fulfill this request. Purchase credits at console.x.com.",
  "platform": "twitter"
}
```

**Action:** Go to [console.x.com](https://console.x.com) → Billing → Credits and purchase credits. Even \$5 is enough for hundreds of API calls.

**Code 417 — OAuth 1.0a App Permissions (HTTP 403)**

Your X Access Token does not have the correct permissions for the requested operation.

```json theme={"system"}
{
  "status": "error",
  "code": 417,
  "message": "Your client app is not configured with the appropriate oauth1 app permissions. Set app to 'Read and write and Direct message', then regenerate your Access Token.",
  "platform": "twitter"
}
```

You may also see the response header `x-access-level: read`, which confirms your Access Token was generated with read-only permissions.

**Action:** In the X Developer Console, update your app permissions to **Read and write and Direct message**, then regenerate your Access Token under Keys and tokens. The new token will inherit the updated permissions. See the [X BYO Key Setup Guide](/dashboard/connect-social-accounts/x-twitter-byo-keys#troubleshooting) for details.

**Code 419 - Missing BYO Credentials (HTTP 400)**

X/Twitter operations require BYO API credentials in the request headers. Ayrshare returns code 419 when both headers are missing, and also when only one of the pair is present. The `message` string varies depending on which header(s) are missing.

When both `X-Twitter-OAuth1-Api-Key` and `X-Twitter-OAuth1-Api-Secret` are missing:

```json theme={"system"}
{
  "action": "x_credentials_required",
  "status": "error",
  "code": 419,
  "message": "X/Twitter operations require your own API credentials. Missing: X-Twitter-OAuth1-Api-Key, X-Twitter-OAuth1-Api-Secret. Please provide your X Developer App credentials in the request headers. See https://docs.ayrshare.com/x-api-setup for setup instructions.",
  "resolution": {
    "docs": "https://docs.ayrshare.com/x-api-setup"
  },
  "platform": "twitter"
}
```

When only one of the pair is present (for example, the key without the secret):

```json theme={"system"}
{
  "action": "x_credentials_required",
  "status": "error",
  "code": 419,
  "message": "You provided X-Twitter-OAuth1-Api-Key but not X-Twitter-OAuth1-Api-Secret. OAuth 1.0a requires both. Missing: X-Twitter-OAuth1-Api-Secret. See https://docs.ayrshare.com/x-api-setup for setup instructions.",
  "resolution": {
    "docs": "https://docs.ayrshare.com/x-api-setup"
  },
  "platform": "twitter"
}
```

**Action:** Send both `X-Twitter-OAuth1-Api-Key` and `X-Twitter-OAuth1-Api-Secret` on every X-bound request. If you provide one without the other, the request is rejected with the same code. See the [X BYO Keys Header Reference](/dashboard/connect-social-accounts/x-twitter-byo-keys#header-reference) for the full header list.

**Code 423 — Legacy X/Twitter OAuth No Longer Supported (HTTP 403)**

Returned when an X/Twitter request relies on the legacy (non-BYO) OAuth path, which is no longer supported. X API access now requires your own X Developer App credentials supplied via request headers.

```json theme={"system"}
{
  "status": "error",
  "code": 423,
  "message": "X (Twitter) API access now requires your own API credentials. Include X-Twitter-OAuth1-Api-Key and X-Twitter-OAuth1-Api-Secret headers in your request. Setup guide: https://docs.ayrshare.com/dashboard/connect-social-accounts/x-twitter-byo-keys",
  "platform": "twitter"
}
```

**Action:** Configure an X Developer App and send the `X-Twitter-OAuth1-Api-Key` and `X-Twitter-OAuth1-Api-Secret` headers on every X-bound request. See the [X BYO Key Setup Guide](/dashboard/connect-social-accounts/x-twitter-byo-keys) for the full setup steps.

### Caption Enhancement Errors

**Code 441 — Caption Enhancement Failed (HTTP 502)**

Returned when a caption enhancement (for example [`shortenLinks`](/apis/post/post)) fails for one or more platforms while preparing a post. Each affected platform appears in the `errors` array with `source: "handlePostAdditions"` and `code: 441`.

When only some platforms fail, the other platforms still post successfully and their results appear in `postIds`. In that case the top-level `status` is `"error"` but `postIds` is non-empty — clients should treat `status` and `errors[]` as complementary rather than mutually exclusive.

```json theme={"system"}
{
  "status": "error",
  "errors": [
    {
      "platform": "twitter",
      "status": "error",
      "source": "handlePostAdditions",
      "code": 441,
      "message": "Caption enhancement failed for twitter. <underlying error>. Post was not sent to this platform."
    }
  ],
  "postIds": [
    {
      "status": "success",
      "id": "...",
      "postUrl": "...",
      "platform": "bluesky"
    }
  ],
  "id": "..."
}
```

If **all** platforms fail enhancement, the response is a top-level `code: 441` with HTTP `502` and no post is created:

```json theme={"system"}
{
  "status": "error",
  "action": "post",
  "code": 441,
  "message": "Caption enhancement failed. See error details for affected platforms.",
  "errors": [
    {
      "platform": "twitter",
      "status": "error",
      "source": "handlePostAdditions",
      "code": 441,
      "message": "Caption enhancement failed for twitter. <underlying error>"
    }
  ]
}
```

**Action:** Caption enhancement failures are typically transient (the underlying shortener or enhancement service returned an error).

* **If `postIds` is non-empty** (some platforms posted successfully), do **not** resubmit the full platform set — that would duplicate the post on the successful platforms. Instead, inspect `errors[]` to identify the failed platforms and retry the request with only those platforms, or rely on your own idempotent retry flow.
* **If `postIds` is empty or missing** (total failure at schedule/post time), safely retry the full request.
* If the failure persists, submit the post without the enhancement flag (for example, drop `shortenLinks`) or contact support.

### Media Fetch / Crawler Access Errors

**Code 440 — Social Network Could Not Download Media (HTTP 400)**

Returned when the platform's publishing crawler cannot download the `mediaUrl` you provided — most commonly because `robots.txt` or a WAF / bot-fight rule is blocking the crawler (for example, Meta's `facebookexternalhit`). The `details` string comes from the upstream platform and is often the Meta/Instagram error 2207052 text.

```json theme={"system"}
{
  "status": "error",
  "errors": [{
    "action": "post",
    "code": 440,
    "message": "The social network could not download media from this URL (for example Instagram/Meta error 2207052). Ensure the file is publicly reachable by the platform's crawlers (e.g. facebookexternalhit), via media bucket's robots.txt file, not only in a browser.",
    "details": "Media download has failed.: The media could not be fetched from the provided URI...",
    "platform": "instagram",
    "status": "error"
  }],
  "postIds": [],
  "id": "..."
}
```

**Code 138 — Instagram Media Fetch Blocked (HTTP 400)**

Fallback code for Instagram media-fetch failures when the upstream response is less specific than the one that triggers code 440. The `details` string typically contains `"Restricted by robots.txt"` or `"HTTP error code 403"`. Code 138 is also used for aspect-ratio / format issues and other generic Instagram errors, so the media-fetch variant is identifiable by the `details` string.

```json theme={"system"}
{
  "status": "error",
  "errors": [{
    "retryAvailable": true,
    "status": "error",
    "code": 138,
    "details": "Media download has failed.: The media could not be fetched from the provided URI. Video download failed with: HTTP error code 403. Restricted by robots.txt",
    "action": "post",
    "platform": "instagram",
    "message": "Instagram Error: Instagram cannot process your post at this time. Please try your post again."
  }],
  "postIds": [],
  "id": "..."
}
```

**Code 379 — Threads Posting Error**

Returned when Threads publishing fails. Most commonly caused by the same media-fetch issue as codes 440 / 138 when publishing to both platforms with the same `mediaUrl`. The Threads API does not return detail strings, so diagnosis usually requires checking for a co-occurring Instagram 440 or 138 in the same publish.

```json theme={"system"}
{
  "status": "error",
  "errors": [{
    "status": "error",
    "code": 379,
    "message": "Error posting to Threads.",
    "action": "post",
    "platform": "threads"
  }],
  "postIds": [],
  "id": "..."
}
```

**Action:** See [Meta Media Crawler Blocked](/help-center/technical-support/meta_media_crawler_blocked) for full troubleshooting, including `robots.txt` snippets and a verification command.

### Facebook Analytics Rate Limit

**Code 444 — Facebook Page Analytics Rate Limit (HTTP 429)**

Returned when a Facebook Page has exceeded Meta's per-Page rate limit on the analytics endpoint. The underlying Meta error is `80001` ("There have been too many calls to this Page account."). The Page remains linked and publishing continues to work — only the analytics fan-out for that Page is throttled.

When the throttle is detected for a single post in a [`/history/facebook`](/apis/history/history-platform) or [analytics](/apis/analytics/social) response, each affected post carries `code: 444` at `facebook.code` with `errCode: 80001`:

```json theme={"system"}
{
  "status": "error",
  "facebook": {
    "action": "rate limit",
    "status": "error",
    "code": 444,
    "errCode": 80001,
    "message": "Facebook Page has hit its per-Page rate limit on the analytics endpoint. Please wait a few minutes and retry.",
    "pageId": "...",
    "id": "..."
  },
  "httpErrorCode": 444,
  "lastUpdated": "...",
  "nextUpdate": "..."
}
```

**Action:** Wait a few minutes and retry. Meta's per-Page rate-limit window typically resolves within the hour without any action on the Page. Do **not** prompt the user to relink the account — this is a transient throttle on Meta's side, not an authorization failure.

<Warning>
  If you previously handled this condition as `code: 161` ("Facebook authorization error … unlink and re-link"), update your integration to recognize `code: 444` and retry with backoff instead of initiating a relink flow. The `161` classification was corrected in April 2026.
</Warning>

### Meta Identity Verification

**Code 326 — Meta Identity Verification Required (HTTP 403)**

Returned when Meta requires additional identity verification for the connected account before it will accept the request. This applies across Meta platforms — Facebook, Instagram, Facebook Groups, Threads, and Messenger. Reconnecting the account does **not** resolve this; the verification must be completed on Meta's side.

```json theme={"system"}
{
  "status": "error",
  "errors": [
    {
      "action": "post",
      "status": "error",
      "code": 326,
      "message": "Meta is requesting additional identity verification for this account. Complete it at https://www.facebook.com/business-support-home and then retry. Reconnecting the account will not resolve this.",
      "platform": "facebook"
    }
  ]
}
```

**Action:** Have the account owner complete Meta's identity verification at [Meta Business Support](https://www.facebook.com/business-support-home), then retry the request. Do **not** prompt the user to relink the account — relinking will not clear this requirement.

### Facebook Account Restriction

**Code 476 — Facebook Account Restriction (HTTP 400)**

Returned when a post to Facebook fails because Meta has placed a restriction on the account (Meta error subcodes `2424009` and `1404078`, or Meta's restriction wording when the error carries no subcode). This is an account-level restriction, not a transient publishing hiccup — it is **non-retryable** and carries **no** `retryAvailable` flag. Resubmitting the same post will not succeed until the restriction is resolved with Meta. The account remains linked to Ayrshare; no relink is required.

Meta does not return the specific restriction reason through the API, so the customer must check Meta's Account Status page directly to see the reason and appeal. When Meta supplies its own verbatim text, Ayrshare surfaces it in the `details` field. Ayrshare also sends the account owner a notification email when the restriction is detected.

```json theme={"system"}
{
  "status": "error",
  "errors": [
    {
      "action": "post",
      "status": "error",
      "code": 476,
      "message": "There is a Facebook restriction on your account. Log in to Facebook, click your profile picture (top-right), open the Help section and select Account Status. Meta's support assistant there surfaces the specific restriction reason (which the API doesn't return) and lets you appeal.",
      "details": "...",
      "platform": "facebook"
    }
  ]
}
```

**Action:** Log in to Facebook, click your profile picture (top-right), open the Help section and select **Account Status**. Meta's support assistant there surfaces the specific restriction reason and lets you appeal. Because the restriction is enforced by Meta at the account level, this code is non-retryable — do not build automatic retry logic around it; resolve the restriction with Meta first.

### Image Format Conversion Errors

Ayrshare automatically converts WebP, HEIC, and AVIF images to JPEG before posting to platforms that don't accept them (Instagram, LinkedIn, TikTok, Google My Business, Threads, and Snapchat for WebP; all platforms for HEIC and AVIF). Conversion runs transparently at send time. The three errors below fire only when the conversion pipeline itself can't complete; if the source image is already in a supported format, no conversion is attempted and these codes will not surface.

**Code 450 — Image Format Conversion Failed (HTTP 400)**

The image was downloaded but could not be re-encoded as JPEG. Most common causes are a corrupt source file, an unexpected internal format inside the container, or an image that exceeds the conversion size cap.

```json theme={"system"}
{
  "status": "error",
  "errors": [
    {
      "action": "image conversion",
      "status": "error",
      "code": 450,
      "message": "The image format could not be converted. The source image may be corrupt or inaccessible. Please verify the media URL and try again.",
      "platform": "instagram"
    }
  ]
}
```

**Action:** Open the source `mediaUrl` directly in a browser to confirm it renders. If it does, re-export the image to a clean JPEG or PNG and retry the post.

**Code 451 — Image Download Failed for Conversion (HTTP 400)**

The conversion pipeline could not fetch the source image. Typical causes include a 4xx/5xx response from the origin, a network timeout, a redirect chain that exceeds the hop limit, or a URL that resolves to a non-public address (blocked by the SSRF guard). The `details` field, when present, carries the underlying cause string.

```json theme={"system"}
{
  "status": "error",
  "errors": [
    {
      "action": "image conversion",
      "status": "error",
      "code": 451,
      "message": "The image could not be downloaded for format conversion.",
      "details": "HTTP 403 from origin",
      "platform": "linkedin"
    }
  ]
}
```

**Action:** Confirm the `mediaUrl` is publicly reachable (no auth, no `robots.txt` blocks, resolves over HTTPS). If the URL redirects, ensure the final destination is also public and not on a private network.

**Code 452 — Converted Image Upload Failed (HTTP 500)**

Conversion succeeded but Ayrshare could not stage the converted JPEG to its temporary storage bucket. This is an internal failure on the Ayrshare side and is retryable.

```json theme={"system"}
{
  "status": "error",
  "errors": [
    {
      "action": "image conversion",
      "status": "error",
      "code": 452,
      "message": "An error occurred uploading the converted image. Please try again.",
      "platform": "tiktok"
    }
  ]
}
```

**Action:** Retry the post. If the error persists across multiple retries, contact support with the `mediaUrl` and approximate timestamp.

### YouTube Transient Upload Errors

The following error codes provide specific signals for YouTube upload failures that are typically transient and safe to retry. Both responses include `retryAvailable: true`, so integrations can branch on that boolean rather than on the HTTP status code.

Most prior `code: 176` responses for YouTube uploads now route to **453** (transient timeout) or **454** (transient service unavailable), both with `retryAvailable: true`. If your integration filters on HTTP 500 to retry YouTube uploads, switch to filtering on the `retryAvailable` field on the response body.

**Code 453 — YouTube Upload Timed Out (HTTP 504)**

Returned when Google's YouTube ingest pipeline timed out while accepting the upload. This is typically transient and resolves on its own within a minute or two.

```json theme={"system"}
{
  "status": "error",
  "errors": [
    {
      "action": "post",
      "status": "error",
      "code": 453,
      "message": "YouTube upload timed out (Google ingest). This is typically transient; please retry in 1–2 minutes.",
      "retryAvailable": true,
      "platform": "youtube"
    }
  ]
}
```

**Action:** Retry the post after 1–2 minutes with exponential backoff. Branch on the `retryAvailable` field on the response body rather than HTTP status to detect retryable failures. You can use the [retry post](/apis/post/retry-post) endpoint to resubmit the same payload.

**Code 454 — YouTube Upload Service Temporarily Unavailable (HTTP 503)**

Returned when YouTube's upload endpoint returns a 5xx status, or when the connection to YouTube was reset or timed out at the socket layer (`ECONNRESET`, `ETIMEDOUT`, `ESOCKETTIMEDOUT`). These conditions are transient.

```json theme={"system"}
{
  "status": "error",
  "errors": [
    {
      "action": "post",
      "status": "error",
      "code": 454,
      "message": "YouTube upload service temporarily unavailable. Please retry.",
      "retryAvailable": true,
      "platform": "youtube"
    }
  ]
}
```

**Action:** Retry the post with exponential backoff. Branch on the `retryAvailable` field on the response body rather than HTTP status to detect retryable failures. You can use the [retry post](/apis/post/retry-post) endpoint to resubmit the same payload.

### YouTube Thumbnail Errors Code 307

Code `307` is returned when a custom YouTube `thumbNail` cannot be applied. When the video itself posts successfully, this does **not** fail the post — the YouTube result keeps `status: "success"` and surfaces the failure additively in a `warnings` array (`feature: "thumbnail"`, `code: 307`). The legacy `thumbnail` sub-object is retained for backward compatibility.

The most common cause is an **unverified YouTube channel**. When a channel has not completed phone verification, YouTube returns an upstream `403` with the generic message `"The authenticated user doesn't have permissions to upload and set custom video thumbnails"`. That wording sounds like an OAuth problem, but in practice it is almost always a verification problem, so verify the channel first. Re-linking the YouTube account is a secondary cause.

```json theme={"system"}
{
  "status": "success",
  "id": "<videoId>",
  "thumbnail": {
    "action": "post",
    "status": "error",
    "code": 307,
    "message": "Your YouTube channel must be verified to set a custom thumbnail. Verify your channel at https://www.youtube.com/verify (phone verification). If your channel is already verified, try unlinking and re-linking your YouTube account to restore permissions.",
    "details": "<upstream message>"
  },
  "warnings": [
    {
      "feature": "thumbnail",
      "code": 307,
      "message": "Your YouTube channel must be verified to set a custom thumbnail. Verify your channel at https://www.youtube.com/verify (phone verification). If your channel is already verified, try unlinking and re-linking your YouTube account to restore permissions.",
      "details": "<upstream message>"
    }
  ]
}
```

Ayrshare also validates the thumbnail before publishing where possible: the file must be a **PNG or JPG/JPEG**, **2MB or less**, and served from a **reachable URL**.

A thumbnail problem **never fails the post** — the video always publishes and the failure is always surfaced as a non-fatal `warnings` entry (top-level `status` stays `"success"`). This holds regardless of when the problem is detected:

* **Caught before upload.** When pre-publish validation can definitively tell the thumbnail is invalid (wrong file type, confirmed over 2MB, or an unreachable URL), Ayrshare skips the thumbnail, still publishes the video, and reports the precise reason in `warnings` — so you avoid a doomed upload attempt and get a clearer message than the provider would return.
* **Caught after upload.** When the failure is only detectable once YouTube processes the request (for example the unverified-channel `403`, or a `413` for an oversized image), the video is already live and the failure is surfaced in the same `warnings` array.

Either way the response looks like the `status: "success"` + `warnings` example shown earlier in this section.

**Action:** Verify your YouTube channel at [https://www.youtube.com/verify](https://www.youtube.com/verify) (phone verification). If your channel is already verified and thumbnails still fail, unlink and re-link your YouTube account in [Social Accounts](https://app.ayrshare.com/social-accounts) and grant all permissions. See [YouTube Thumbnail Not Applied (Unverified Channel)](/help-center/technical-support/youtube_thumbnail_unverified_channel) for the full troubleshooting guide.

### Reddit Posting Errors

**Code 442 — Reddit Banned Subreddit (HTTP 400)**

Returned when the account has been banned from posting to the target subreddit. This is **not** retryable — the post will not succeed if resubmitted as-is. The message includes the affected subreddit name (for example, `r/news`).

```json theme={"system"}
{
  "status": "error",
  "errors": [
    {
      "action": "post",
      "status": "error",
      "code": 442,
      "message": "You've been banned from posting to r/news. This post will not succeed on retry — remove it from your target subreddits.",
      "platform": "reddit"
    }
  ]
}
```

**Action:** Remove the banned subreddit from your target subreddits. Retrying the post unchanged will not succeed.

**Code 443 — Reddit Disallowed Word in Title (HTTP 400)**

Returned when a subreddit rejects the post because its title contains a disallowed word. Edit the title before retrying — resubmitting as-is will not succeed. The message includes the affected subreddit name (for example, `r/news`).

```json theme={"system"}
{
  "status": "error",
  "errors": [
    {
      "action": "post",
      "status": "error",
      "code": 443,
      "message": "r/news rejected this post because the title contains a disallowed word. Edit the title before retrying — retrying as-is will not succeed.",
      "platform": "reddit"
    }
  ]
}
```

**Action:** Edit the post title to remove the disallowed word, then retry.

### Moderation Errors

**Code 438 — Moderation Input Rejected (HTTP 400)**

Returned by [`POST /validate/moderation`](/apis/post/post) when the AI provider rejects the supplied input — for example, an unsupported file type. This is an input problem with the request, not a transient processing failure.

```json theme={"system"}
{
  "status": "error",
  "errors": [
    {
      "action": "moderation",
      "status": "error",
      "code": 438,
      "message": "There was an issue with the AI processing."
    }
  ]
}
```

**Action:** Verify the moderation input is valid and uses a supported file type, then resubmit.

<Note>
  Contrast code 438 with **code 331**. Code 331 covers the same moderation scenario but represents a genuine processing failure on the provider side (HTTP 500, message "There was an issue with the AI processing. Please try again."). Code 331 is a transient server-side failure you can retry, whereas code 438 indicates the input itself was rejected and must be corrected before retrying.
</Note>

### LinkedIn Analytics Errors

**Code 475 — Re-link LinkedIn Profile for Analytics (HTTP 403)**

Returned by [`POST /analytics/post`](/apis/analytics/post) and [`POST /analytics/social`](/apis/analytics/social) for a personal (member) LinkedIn profile that was linked before member analytics shipped. These profiles lack the LinkedIn member analytics scopes (`r_member_postAnalytics`, `r_member_profileAnalytics`), so LinkedIn rejects the analytics request. Posting is unaffected.

```json theme={"system"}
{
  "action": "authorization",
  "status": "error",
  "code": 475,
  "message": "Your LinkedIn profile is missing the analytics permissions. Please re-link your LinkedIn profile to enable analytics.",
  "resolution": {
    "relink": true,
    "platform": "linkedin"
  }
}
```

**Action:** Have the account owner re-link their LinkedIn profile in [Social Accounts](https://app.ayrshare.com/social-accounts) to grant the new analytics scopes, then retry the analytics request. After re-linking, allow a few minutes before the error clears: Ayrshare caches this error briefly and LinkedIn also caches the token's permissions, so a re-linked profile can keep returning code `475` for up to \~5-10 minutes before analytics succeed.

### TikTok Comment Errors

**Code 288 — TikTok Comment Deferred / Post Still Processing (HTTP 400)**

TikTok processes videos asynchronously, so a freshly published post's `id` is `"pending"` until TikTok's `post.publish.publicly_available` webhook resolves the real video id. A [get-comments](/apis/comments/get-comments), comment, or reply request against a post that is still processing (or one whose `id` is `"failed"`) is refused before any call to TikTok and returns code 288 instead of a generic failure.

```json theme={"system"}
{
  "status": "error",
  "errors": [
    {
      "action": "get",
      "status": "error",
      "code": 288,
      "message": "TikTok video is still processing; the action is deferred until the post is live.",
      "platform": "tiktok"
    }
  ]
}
```

**Action:** Wait until TikTok finishes processing, then retry. Listen for the [`tikTokPublished` Scheduled Action webhook](/apis/webhooks/actions#scheduled-action) or poll [/history](/apis/history/overview) until the post `id` is the resolved numeric video id. A [first comment](/apis/post/overview#first-comment) is posted automatically once the post resolves, so it does not need to be retried. For a `"failed"` post the message instead notes the video failed to publish and the action will not run.

### Error Message Translation

The API error message response can be automatically translated to the language of your choice.
This is useful if you want to display the error directly to your user in their preferred language.

See here if you want to [choose the language of the social linking page](/multiple-users/manage-user-profiles#set-language-for-the-social-linking-page).

In the header include:

```json theme={"system"}
"Translate-Error-Message": "Language_Code"
```

Where the `Language_Code` is one of the available[ language codes](/iso-codes/language).

For example, the following will translate the error to French.

```json theme={"system"}
"Translate-Error-Message": "fr" // Translate to French
```

Our system will automatically detect the error message language.
