> ## Documentation Index
> Fetch the complete documentation index at: https://developers.apob.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Social media imports

> Submit a social media URL and query import status, stage progress, and verified files.

Use these authenticated GraphQL operations to import publicly accessible media
you have permission to use. A successful submission means the import was accepted;
it does not mean the file is ready. These operations do not start generation.

## Supported sources

| Source | Images | Videos |
| - | - | - |
| Instagram post or reel | Single images and carousel images | Single videos and carousel videos |
| TikTok post | Photo posts | Videos |
| YouTube, including `youtu.be` and Shorts | Not supported | Videos |

Profile, search and playlist URLs are not import inputs. Sharing parameters are
removed when identifying the post. Private, deleted or unavailable posts can fail.
An image request does not substitute a video's thumbnail.

The import accepts at most 20 selected assets. Limits are 20 MiB per image,
200 MiB per video, 40 million pixels per asset, and 10 minutes per video. Images
must be decodable static JPEG, PNG or WebP; WebP requires an available decoder.
Videos must be valid MP4 or WebM. Validation failures are returned as import errors.

## Submit an import

```graphql theme={"system"}
mutation CreateMediaImport($input: CreateMediaImportInput!) {
  createMediaImport(input: $input) {
    importId
    status
    stage
    progress { current total queued checkTime finishCode }
    errorCode
    displayErrorMessage
  }
}
```

```json theme={"system"}
{
  "input": {
    "requestId": "client-request-001",
    "sourceUrl": "https://www.instagram.com/p/EXAMPLE_POST/",
    "mediaType": "IMAGE"
  }
}
```

Authenticate with `Authorization: Bearer <APOB_API_KEY>`. See
[authentication](https://developers.apob.ai/api-reference/authentication.md) for Firebase login support.

| Input | Required | Meaning |
| - | - | - |
| `requestId` | Yes | Your request identifier: 1–128 ASCII letters, digits, `.`, `_`, `:`, or `-`. |
| `sourceUrl` | Yes | A supported HTTPS post/video URL, up to 4,096 characters. |
| `mediaType` | Yes | `IMAGE` or `VIDEO`; selects matching assets from the post. |

If the response is lost, repeat the same input with the **same `requestId`** to
recover its `importId`. Reusing that identifier with different input returns
error `380005`. Submission is limited to 60 requests per account per hour.

## Query status and results

```graphql theme={"system"}
query GetMediaImport($importId: ID!) {
  getMediaImport(importId: $importId) {
    importId
    status
    stage
    progress { current total queued checkTime finishCode }
    assets {
      assetKey
      mediaType
      s3Url
      previewUrl
      sizeBytes
      width
      height
      durationMilliseconds
    }
    errorCode
    displayErrorMessage
  }
}
```

Only the submitting account can query the import. Poll at a modest interval,
such as every 3–5 seconds, while it is `PENDING` or `RUNNING`. Querying does not
start another crawl or download.

| Status | Meaning |
| - | - |
| `PENDING` | Accepted and awaiting execution. |
| `RUNNING` | Resolving, crawling, transferring, or verifying media. |
| `READY` | Every selected asset has been verified and the result saved. |
| `FAILED` | The import ended with an error. Already verified assets can remain in `assets`. |

Stages are `QUEUED`, `RESOLVING`, `SCRAPING`, `DOWNLOADING`, `VERIFYING`,
`COMPLETED`, and `FAILED`. Progress uses `current / total`, with `total = 100`.
It measures completed stages/items, not exact byte transfer or external service
progress. It can stay unchanged while work continues. Only `READY` reaches 100.
`finishCode` is null while active, 0 for success, and 1 for failure.

`s3Url` is the stored asset reference. `previewUrl` opens inline in a browser
and is temporary; query again when it expires. Fragmented MP4 imports are
repackaged for preview without re-encoding, resizing, or adding an audio track.
Video duration is in milliseconds; image duration is null. Only
verified assets appear in the response.

## Failures and retries

Input, authentication and ownership failures appear in GraphQL `errors`. HTTP
200 alone does not mean the operation succeeded. For example, changing the input
of an existing request identifier returns:

```json theme={"system"}
{
  "errors": [{"message": "[380005]", "path": ["createMediaImport"]}],
  "data": null
}
```

The example shows only key fields; responses can also include `locations` and
`extensions`. Business codes use the existing numeric code in the message;
there is no `extensions.code` field contract.

Accepted work reports failures through `status: FAILED`, `errorCode`, and
`displayErrorMessage`. `errorCode` remains a nullable GraphQL **String** containing
the decimal business code, for example `"380008"`. Older imports are translated
to the same codes when queried. Display text can be localized; branch on the
code rather than matching message text. Handle both GraphQL errors and failed
import results.

| Code | Meaning and handling |
| - | - |
| `100101` | Missing or invalid authentication. Restore authentication before retrying. |
| `320001` | Request rate limit exceeded. Wait before retrying. |
| `380001` | Invalid input/request identifier. Correct the request. |
| `130120` | Invalid URL, HTTPS scheme, length or URL structure. Correct the URL. |
| `380002` / `380003` / `380004` | Unsupported platform, social URL route or media type. Choose a supported source. |
| `380005` | Request identifier conflict. Network retries must keep the original identifier and input. |
| `380006` | Import missing or inaccessible to this account/environment. Use an import owned by the caller. |
| `380007` | Import service is not configured. Contact support. |
| `380008` | Submission outcome unknown. Retain the import ID and investigate before any fresh submission. |
| `380009` | Crawl submission was rejected. Display the error; do not loop on fresh requests. |
| `380010` / `380011` / `250102` | Source unavailable, crawl failed or import timed out. Preserve the import ID for investigation. |
| `380012` | File exceeds its size limit. Choose a smaller file. |
| `380013` / `380014` / `380026` | Invalid dimensions, video or image data. Choose a valid source within the limits. |
| `380036` | Video exceeds the 10-minute import limit. This is an expected validation rejection. Choose a video of 10 minutes or less; do not automatically retry the same source. |
| `380015` / `380016` / `380022` | Unsupported image format, animated image or video format. Choose a supported static image or video. |
| `380017` / `380018` | Short link unresolved or too many redirects. Try the supported canonical post/video URL. |
| `380025` | Import was cancelled. Preserve its ID; cancellation does not prove external work was never accepted. |
| `380032` / `380033` | No matching media or too many assets. Select the appropriate media type or a smaller post. |
| `380000`, `380019`–`380021`, `380023`–`380024`, `380027`–`380031`, `380034`–`380035` | Import/result validation or storage/state failure. Preserve the import ID and contact support; do not automatically create a replacement task. |

`380008` means the external service may have accepted the crawl but
its receipt could not be recovered. Do not automatically submit a fresh request
identifier to retry it; that can purchase the same external work twice. Retain
the import identifier for investigation.

Completed files can be reused for the same platform/post/item identity. Failed
transfers retry whole files; partial-byte resume is not supported. A multi-image
post may still require another metadata lookup before its item identities are known.

For a known single video, concurrent imports continue sharing the original crawl
while its completed result waits for file transfer. A worker interruption during
this handoff resumes from the saved result without submitting another crawl.

Imports waiting on the same video report the original import's known failure,
such as `380032` when no matching media was found. This is distinct from an
unknown submission outcome; waiting does not automatically start another crawl.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.