Skip to main content
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

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

Authenticate with Authorization: Bearer <APOB_API_KEY>. See authentication for Firebase login support. 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

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. 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:
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. 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.