---
updatedAt: 2026-09-30T21:31:46.000Z
agentTools:
  siteIndex: https://developer-docs.amazon/llms.txt
  projectIndex: https://developer-docs.amazon/sp-api/llms.txt
---

# A+ Content Troubleshooting Guide

Learn how to handle common errors from the A+ Content API.

This guide is organized by scenario. For the error response envelope, authorization, throttling and retries, refer to [Error Response](https://developer-docs.amazon/sp-api/docs/response-format#error-response) and [Usage plans and rate limits](https://developer-docs.amazon.com/sp-api/docs/usage-plans-and-rate-limits). For module fields and limits, refer to the [A+ Content Management API reference](https://developer-docs.amazon.com/sp-api/reference/a-content-management-v2020-11-01).

## Error response patterns

The API uses the standard SP-API error envelope. The following patterns are common with A+ Content and explain most of the responses in this guide.

| Situation                                                             | Response                                                                                                                  | Interpretation                                                                                                                                                                                                                                                       |
| --------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| A field breaks a constraint (required, length, pattern, minimum size) | 400, code InvalidInput, message "The request is not valid, please check the inputs and try again."                        | The constraint is in `details`, one entry per failing field: `Request failed validation: <operation>.<field path>: <constraint>`. Document-level rules (one tier per document, module cap) are checked only once every field passes and come back as a single entry. |
| The JSON does not match the model (a misnamed or misplaced property)  | 400, code InvalidInput, message "The request syntax is malformed and unparseable, please check the inputs and try again." | `details` names the unexpected property and the properties allowed at that position. Nothing else in the body was validated yet.                                                                                                                                     |
| A dry run finds an asset it cannot read                               | 200 from `validateContentDocumentAsinRelations` with a populated `errors` array                                           | A successful status does not mean the document is clean. Always read `errors` and `warnings` on 200 responses.                                                                                                                                                       |
| Access is refused, for any reason                                     | 403, code Unauthorized                                                                                                    | The message identifies the cause: missing authorization or role ("Access to requested resource is denied."), a document from another marketplace, an ASIN the selling partner is not allowed to use, or an application without Media API access.                     |
| The content reference key does not exist                              | 404 with two `NOT_FOUND` entries                                                                                          | Both entries describe the same condition.                                                                                                                                                                                                                            |

A field-level validation error:

```json
{
  "errors": [
    {
      "code": "InvalidInput",
      "message": "The request is not valid, please check the inputs and try again.",
      "details": "Request failed validation: validateContentDocumentAsinRelations.postContentDocumentRequest.contentDocument.contentModuleList[0].premiumHotspotImageText.hotSpots[1]: hotspot placement out of bounds"
    }
  ]
}
```

A JSON shape error (here `body` was sent where a Premium text module expects `description`):

```json
{
  "errors": [
    {
      "code": "InvalidInput",
      "message": "The request syntax is malformed and unparseable, please check the inputs and try again.",
      "details": "JSON, line: 1, column: 118, unexpected property name: 'body', expected property names: [description, headline]"
    }
  ]
}
```

A 200 from the dry run that still carries a warning and an error:

```json
{
  "warnings": [
    { "code": "ASIN_FAILED_VALIDATION", "message": "", "details": "INVALIDASIN" }
  ],
  "errors": [
    {
      "code": "CONTENT_FAILED_VALIDATION",
      "message": "We can't read one of the images that you uploaded. Please save the image in PNG format and upload again. See image: Asset access forbidden: Unable to validate project due to inaccessible media assets.",
      "details": ""
    }
  ]
}
```

## Building a content document

These scenarios return Bad Requests 400 errors for `createContentDocument`, `updateContentDocument` and `validateContentDocumentAsinRelations` alike. You can run the dry run (`validateContentDocumentAsinRelations`) to get the same problems before persisting a document.

| Scenario                                                                                                                                                                                       | Response                                                                                                                  | Action to Take                                                                                                                                                                                                                      |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| The document mixes Standard and Premium modules                                                                                                                                                | "Content documents cannot contain both premium and standard module types."                                                | Keep a document entirely Standard or entirely Premium. Brand Story modules belong in their own document with `contentType` set to BrandStory.                                                                                       |
| A Premium document has more than seven modules                                                                                                                                                 | "Content module lists cannot have more than 7 modules."                                                                   | Trim to seven. The limit applies as soon as the list contains one Premium module; Standard-only documents are not capped by the API.                                                                                                |
| The module object is missing or does not match the declared type                                                                                                                               | "Content missing for given content module type!"                                                                          | The module object key must match `contentModuleType` (for example `premiumImageText` for PREMIUM\_IMAGE\_TEXT).                                                                                                                     |
| A property is misnamed or misplaced: a list item sent without its wrapper, `body` instead of `description` on a Premium text module, or the ASIN set placed in the body of the validation call | JSON shape error; details lists the accepted property names at that position                                              | Follow the model. List items are wrapped (`techSpecs[].techSpec`, `faqs[].faq`, `carouselCards[].imagePanel`, `hotSpots[].imageTextHotSpot`). The ASIN set of the validation call is the comma-separated query parameter `asinSet`. |
| The content type is not a supported value                                                                                                                                                      | "contentType: must not be null"                                                                                           | Use EBC for sellers, EMC for vendors, BrandStory for Brand Story.                                                                                                                                                                   |
| The locale is written with an underscore                                                                                                                                                       | "locale: must match" followed by the pattern `^[a-z]{2,}-[A-Z0-9]{2,}$`                                                   | Send the hyphen form (en-US). Publish records report the underscore form (en\_US); that field is read-only.                                                                                                                         |
| An image crop is smaller than the module allows                                                                                                                                                | "`imageCropSpecification.size.width.value`: must be greater than or equal to N" (or height)                               | The crop is checked against the module's minimum size and aspect ratio, not against the uploaded file. Notable minimums: Brand Story logo 362 x 453, hotspot mobile image 600 x 450.                                                |
| A hotspot marker sits too close to the image edge or to another marker                                                                                                                         | "hotspot placement out of bounds", "overlaps with hotspot at index N" or "invalid coordinate format"                      | Coordinates are pixel offsets on the 1464 x 600 desktop image. Keep x between 23 and 1441, y between 23 and 577, and markers at least 95 px apart. Hotspot items have no position property.                                         |
| A carousel button label is too long                                                                                                                                                            | "`buttonText.value`: length must be between 0 and 12"                                                                     | Twelve characters at most.                                                                                                                                                                                                          |
| Two carousel cards share a position                                                                                                                                                            | "Duplicate position found: N"                                                                                             | Positions are unique within one module.                                                                                                                                                                                             |
| Text exceeds a module limit                                                                                                                                                                    | "Total text items N exceeds maximum of M", "Total text length N exceeds maximum of M" or "length must be between A and B" | The bound is in the message; limits are per field and per module type.                                                                                                                                                              |

## Attaching ASINs and publishing

Validation and ASIN relations are permissive. Ownership, brand eligibility and account entitlements are enforced when the document is created or submitted, and one document per ASIN and content family (A+ or Brand Story) is live at a time.

| Scenario                                                                 | Response                                                                                                                                                                             | Action to Take                                                                                                                                                                                        |
| ------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| The dry run is clean, but creating a Brand Story document fails          | 400 InvalidInput, "User \[<merchantId>] shouldn't be using project type: \[BrandStory]"                                                                                              | Validation does not check account entitlements. Brand Story requires Brand Registry enrollment; nothing in the request needs to change.                                                               |
| ASINs were attached without complaint, yet some are unusable             | postContentDocumentAsinRelations returns 200 for any ASIN, an empty set included                                                                                                     | Read listContentDocumentAsinRelations with `includedDataSet=METADATA`: an unusable ASIN carries the warning `ASIN_FAILED_VALIDATION` and a badge such as `BRAND_NOT_ELIGIBLE` or `CATALOG_NOT_FOUND`. |
| Submission is refused because an ASIN is outside the brand               | 403 Unauthorized, "You are unable to add content to this ASIN because our system does not recognize this ASIN as part of your brand." together with "Failed asin permissions check." | Post the ASIN set again without the ineligible ASINs, then submit.                                                                                                                                    |
| Submission is refused because Amazon Retail owns the content on the ASIN | "You are unable to add content to this ASIN because there is an existing retail contribution on this ASIN."                                                                          | The selling partner asks Selling Partner Support (sellers) or their Vendor Manager (vendors) to release the ASIN; the API cannot override it.                                                         |
| An approved document went back to DRAFT                                  | Posting ASIN relations to an approved document, or updating it, resets the status (200, no warning)                                                                                  | Submit again. The approved revision stays live until the new one is approved.                                                                                                                         |
| A document is APPROVED but no longer appears on the detail page          | Approving another document of the same family on the same ASIN takes over the publish record silently                                                                                | Check searchContentPublishRecords for the ASIN before submitting. The replaced document's relation badge reads `CONTENT_NOT_PUBLISHED`.                                                               |
| Reading a document is refused although the key is correct                | 403 Unauthorized, "The A+ content belongs to another marketplace: <code>."                                                                                                           | Use the marketplace the document was created in.                                                                                                                                                      |
| getContentDocument returns metadata but no content                       | `includedDataSet` was repeated as separate parameters; only the first is kept                                                                                                        | Pass one comma-separated value: `includedDataSet=CONTENTS,METADATA`.                                                                                                                                  |
| The dry run reports an image it cannot read                              | 200 with an error `CONTENT_FAILED_VALIDATION`, "We can't read one of the images that you uploaded..."                                                                                | Upload the file to its pre-signed URL before referencing the upload destination id.                                                                                                                   |
| The document is `APPROVED` seconds after submission                      | Some accounts are approved automatically                                                                                                                                             | Poll until `APPROVED` or `REJECTED`; do not wait for `SUBMITTED`.                                                                                                                                     |
| A publish record says EBC for a Premium document                         | Publish records carry the content family, not the tier                                                                                                                               | The tier is `badgeSet` (`PREMIUM` or `STANDARD`; empty for Brand Story) on getContentDocument and searchContentDocuments.                                                                             |

Submission refused for an ASIN outside the brand:

```json
{
  "errors": [
    {
      "code": "Unauthorized",
      "message": "You are unable to add content to this ASIN because our system does not recognize this ASIN as part of your brand.",
      "details": ""
    },
    { "code": "Unauthorized", "message": "Failed asin permissions check.", "details": "" }
  ]
}
```

The same ASIN seen through listContentDocumentAsinRelations with `includedDataSet=METADATA`:

```json
{
  "warnings": [
    {
      "code": "ASIN_FAILED_VALIDATION",
      "message": "You are unable to add content to this ASIN because our system does not recognize this ASIN as part of your brand.",
      "details": "B000000000"
    }
  ],
  "nextPageToken": null,
  "asinMetadataSet": [
    {
      "asin": "B000000000",
      "badgeSet": ["CONTENT_NOT_PUBLISHED", "BRAND_NOT_ELIGIBLE"],
      "parent": "B000000000",
      "title": "Example product title",
      "imageUrl": "https://m.media-amazon.com/images/I/example.jpg",
      "contentReferenceKeySet": null
    }
  ]
}
```

## Media API

Media such as Videos and their thumbnails are registered with createMedia before a content document references them. The following error scenarios are possible:

| Scenario                                                                                                    | Response                                                                                                                                                                                                                      | Action to Take                                                                                                                                                                                                                                                      |
| ----------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| The upload destination for a media file is refused                                                          | 403 Unauthorized from `createUploadDestinationForResource` on a media-specific resource path                                                                                                                                  | Media files use the same Uploads resource as images, `aplus/2020-11-01/contentDocuments`. The returned ids look like `aplus-media/sc/<uuid>.mp4`.                                                                                                                   |
| The upload destination id is not accepted                                                                   | "`uploadDestinationId` must be a valid `uploadDestinationId` returned by `createUploadDestination`"                                                                                                                           | Pass the id exactly as the Uploads API returned it.                                                                                                                                                                                                                 |
| Both, or neither, of a new upload and an existing asset are referenced                                      | "Exactly one of `uploadDestinationId` or `mediaId` is required"                                                                                                                                                               | Reference a new upload or an existing asset, not both.                                                                                                                                                                                                              |
| A video has no thumbnail, or more than one                                                                  | "`relatedMedia` must not be null or empty" or "`relatedMedia` must contain exactly one entry"                                                                                                                                 | One `relatedMedia` entry with association type `VIDEO_PAIRING` and the image.                                                                                                                                                                                       |
| A video title is too short or all uppercase                                                                 | "`title` must contain at least 3 words" or "Video title must not be all uppercase: \[...]"                                                                                                                                    | Give the pairing a descriptive title of three or more words.                                                                                                                                                                                                        |
| A video has no descriptions, duplicate locales or an unsupported locale, or an image was given descriptions | "`descriptions` must not be null or empty", "`descriptions` must not contain duplicate locales: <locale>", "`descriptions` contains an unsupported locale", "Descriptions are not valid for image assets."                    | Videos take one description per locale; images take none.                                                                                                                                                                                                           |
| The same file is registered again with a different title or descriptions                                    | 409 CONFLICT, "Image title conflicts with existing metadata..." or "The provided descriptions conflict with existing video-level descriptions..."                                                                             | Registering identical metadata again is idempotent (200 with the same ids). Change titles and descriptions with updateMedia.                                                                                                                                        |
| Updating a video's title or descriptions is refused                                                         | "Title updates on videos require `associatedMediaId` to target a specific pairing.", "Exactly one of `title` or `descriptions` is required" or "`associatedMediaId` is only valid when updating title"                        | A title belongs to a video-thumbnail pairing: PATCH the video with `associatedMediaId=<thumbnail mediaId>` and a body containing only `title`. Descriptions belong to the video: a body containing only `descriptions`, no associated id. Images take a title only. |
| A media id is unknown                                                                                       | 404 NOT\_FOUND, "We cannot find this media metadata."                                                                                                                                                                         | Use the ids returned by createMedia.                                                                                                                                                                                                                                |
| A document with a video module is refused                                                                   | "`videoMediaId` and `imageMediaId` are required for all video components", "Media <id> is not a video", "`imageMediaId` is not associated with `videoMediaId`", or 404 "Video metadata for `videoMediaId` <id> was not found" | Use the video's `mediaId` and the thumbnail id from its `relatedMedia`; create the pairing with createMedia first.                                                                                                                                                  |
| A video stays in `PENDING_PROCESSING` and `PENDING_AMAZON`                                                  | Processing and moderation can take up to 48 hours                                                                                                                                                                             | Keep polling getMedia. A document whose video fails processing is not published; Amazon does not publish it with the video modules removed.                                                                                                                         |

Registering a file again with a different title:

```json
{
  "errors": [
    {
      "code": "CONFLICT",
      "message": "The request conflicts with the current state of the resource.",
      "details": "Image title conflicts with existing metadata. Image with mediaId 13450992-fe99-4add-a939-540d7cd10a35 already has title 'Sample thumbnail image renamed', provided: 'A different title here'. Use updateMedia to change the title."
    }
  ]
}
```