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

# Upload from URL

> Upload a file from an existing URL.

Fetch a remote URL and store the result as a PostQueen media asset. Useful when your media already lives on a CDN or external storage and you do not want to round-trip it through your client.

## Requirements for the source URL

* Must be reachable from the PostQueen backend (publicly resolvable HTTPS, no auth required).
* The URL path, ignoring any query string, must end in `.png`, `.jpg`, `.jpeg`, `.gif`, `.webp` or `.mp4`. This is checked before the fetch, so AVIF, BMP and TIFF cannot be pulled from a URL at all even though [Upload File](/public-api/uploads/upload-file) accepts them.
* The downloaded bytes are then sniffed and must also land in that same allowlist.
* PostQueen performs an [SSRF-safe fetch](https://github.com/nodejs/undici): private IP ranges, link-local addresses, and `localhost` are rejected.

## Example

```bash theme={"system"}
curl -X POST "https://api.postqueen.ai/public/v1/upload-from-url" \
  -H "Authorization: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com/photo.jpg"}'
```

Response shape matches [Upload File](/public-api/uploads/upload-file).

## When to prefer multipart upload

If your source URLs are slow or unreliable, the round-trip through PostQueen can fail or take a long time. For best results:

* Cache stable, fast HTTPS source URLs, such as S3, R2 or Cloudflare Images.
* For one-off uploads, pre-download the file locally and POST it to [`/public/v1/upload`](/public-api/uploads/upload-file) instead.
* Do not link to signed URLs that may expire before PostQueen fetches them.

Common failure modes: [Uploads troubleshooting](/troubleshooting/uploads).


## OpenAPI

````yaml POST /upload-from-url
openapi: 3.1.0
info:
  title: PostQueen Public API
  description: >-
    API for managing social media posts, integrations, and media uploads in
    PostQueen.


    ## Authentication


    All endpoints require an API key passed in the `Authorization` header:


    ```

    Authorization: your-api-key

    ```


    Get your API key from PostQueen Settings.


    ## Rate Limits


    The create-post endpoint is capped per organization per hour. With
    `API_LIMIT` unset the ceiling is **90 requests per hour**; the shipped
    Compose files and PostQueen Cloud both set it to **30**. No other endpoint
    is throttled.


    ## Terminology


    The UI uses `channel`, but the API uses `integration`. They refer to the
    same thing.


    ## Supported Platforms (34)


    **Social Platforms:** X (Twitter), LinkedIn, LinkedIn Page, Facebook,
    Instagram, Instagram Standalone, Threads, Bluesky, Mastodon, Warpcast
    (Farcaster), Nostr, VK


    **Video Platforms:** YouTube, TikTok


    **Community Platforms:** Reddit, Lemmy, Discord, Slack, Telegram, Kick,
    Twitch


    **Design Platforms:** Pinterest, Dribbble


    **Blogging Platforms:** Medium, Dev.to, Hashnode, WordPress, Moltbook


    **Business:** Google My Business (GMB), Listmonk (newsletters), Whop, Skool
  license:
    name: MIT
  version: 1.0.0
servers:
  - url: https://api.postqueen.ai/public/v1
    description: PostQueen Cloud
  - url: https://{host}/api/public/v1
    description: Self-hosted
    variables:
      host:
        default: localhost:4007
        description: Your PostQueen instance domain
security:
  - ApiKeyAuth: []
tags:
  - name: Integrations
    description: Manage connected social media channels
  - name: Posts
    description: Create, list, and delete posts
  - name: Uploads
    description: Upload media files
  - name: Notifications
    description: View organization notifications
  - name: Analytics
    description: View analytics for integrations and posts
  - name: Video Generation
    description: Generate videos with AI
  - name: OAuth
    description: Authorize third-party apps and exchange codes for access tokens
paths:
  /upload-from-url:
    post:
      tags:
        - Uploads
      summary: Upload from URL
      description: Upload a file from an existing URL.
      operationId: uploadFromUrl
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                url:
                  type: string
                  format: uri
                  description: URL of the file to upload
              required:
                - url
            example:
              url: https://example.com/image.png
      responses:
        '200':
          description: File uploaded successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MediaFile'
components:
  schemas:
    MediaFile:
      type: object
      properties:
        id:
          type: string
          description: Unique file ID
        name:
          type: string
          description: Stored file name
        originalName:
          type:
            - string
            - 'null'
          description: The name the file was uploaded under
        path:
          type: string
          description: Public URL of the file. This is the value to send as an attachment
        thumbnail:
          type:
            - string
            - 'null'
          description: Thumbnail URL, set for video
        alt:
          type:
            - string
            - 'null'
          description: Alt text, when one was set
      example:
        id: e639003b-f727-4a1e-87bd-74a2c48ae41e
        name: image.png
        originalName: launch-banner.png
        path: https://uploads.postqueen.ai/image.png
        thumbnail: null
        alt: null
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: Authorization
      description: Your PostQueen API key

````