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

# Attach media from URL

> Downloads up to 10 public files and appends them to the post's media. Each URL must serve the file itself: redirects are not followed, and web pages, private-network hosts and files over the type's size cap are refused. Each download must finish within 20 seconds. Only the types the post's channel accepts are kept. URLs that could not be attached are listed in `failed_urls`, and `failures` gives the reason of each. Posts that are publishing, published, partially published or failed cannot take media: when a file was downloaded, the request fails with `422` on `post` with `This post has already been processed and cannot be re-published. Duplicate it to try again.` Accepted files: JPEG, PNG, GIF and WebP images (HEIC and HEIF too when the server can convert them, stored as JPEG), MP4 and MOV videos, and PDF documents. Size caps: 10 MB per image (and at most about 67 megapixels, 8192 × 8192 pixels in total), 1 GB per video, 100 MB per PDF. Each network enforces its own, usually smaller, caps when the post is scheduled or published (`GET /content-types`). On Pinterest and TikTok the content type is chosen again from the post's media, as on create.



## OpenAPI

````yaml /openapi.json post /posts/{post}/media/from-url
openapi: 3.1.0
info:
  title: TryPost API
  version: 2.0.0
  description: >-
    REST API for TryPost. Authenticate with a workspace API key as a Bearer
    token.
servers:
  - url: https://app.trypost.it/api
    description: TryPost Cloud
security:
  - bearerAuth: []
tags:
  - name: Posts
    description: Create, read, update, delete and preview posts.
  - name: Post notes
    description: Internal notes on a post, visible to workspace members.
  - name: Approvals
    description: Approve or reject posts waiting for approval.
  - name: Recurrence
    description: Make a post repeat on a schedule.
  - name: Media and uploads
    description: Upload files and attach media to posts.
  - name: Social accounts
    description: Connected social accounts and their network-specific options.
  - name: Channels
    description: A channel's posting schedule and queue.
  - name: Ideas
    description: Ideas on the Create board.
  - name: Idea stages
    description: The groups (columns) of the ideas board.
  - name: Analytics
    description: Workspace and channel insights.
  - name: Labels
    description: Labels to organize posts and ideas.
  - name: Signatures
    description: Reusable text to append to posts.
  - name: Workspace
    description: The workspace the API key belongs to.
  - name: API keys
    description: Personal API keys for this workspace.
  - name: Webhooks
    description: Outgoing webhooks and their delivery logs.
  - name: Repurposes
    description: Automations that republish videos posted outside TryPost.
  - name: Platform
    description: Platform capabilities and content types.
paths:
  /posts/{post}/media/from-url:
    parameters:
      - $ref: '#/components/parameters/PostId'
    post:
      tags:
        - Media and uploads
      summary: Attach media from URL
      description: >-
        Downloads up to 10 public files and appends them to the post's media.
        Each URL must serve the file itself: redirects are not followed, and web
        pages, private-network hosts and files over the type's size cap are
        refused. Each download must finish within 20 seconds. Only the types the
        post's channel accepts are kept. URLs that could not be attached are
        listed in `failed_urls`, and `failures` gives the reason of each. Posts
        that are publishing, published, partially published or failed cannot
        take media: when a file was downloaded, the request fails with `422` on
        `post` with `This post has already been processed and cannot be
        re-published. Duplicate it to try again.` Accepted files: JPEG, PNG, GIF
        and WebP images (HEIC and HEIF too when the server can convert them,
        stored as JPEG), MP4 and MOV videos, and PDF documents. Size caps: 10 MB
        per image (and at most about 67 megapixels, 8192 × 8192 pixels in
        total), 1 GB per video, 100 MB per PDF. Each network enforces its own,
        usually smaller, caps when the post is scheduled or published (`GET
        /content-types`). On Pinterest and TikTok the content type is chosen
        again from the post's media, as on create.
      operationId: attachMediaFromUrl
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - urls
              properties:
                urls:
                  type: array
                  minItems: 1
                  maxItems: 10
                  items:
                    type: object
                    required:
                      - url
                    properties:
                      url:
                        type: string
                        format: uri
                        description: Public `http` or `https` URL whose host resolves.
                      alt:
                        type:
                          - string
                          - 'null'
                        maxLength: 2000
                        description: Alt text. Applies to images only.
            example:
              urls:
                - url: https://example.com/launch.jpg
                  alt: Product launch banner
                - url: https://example.com/teaser.mp4
      responses:
        '200':
          description: The post and the result of each URL.
          content:
            application/json:
              schema:
                type: object
                properties:
                  post:
                    $ref: '#/components/schemas/Post'
                  attached_count:
                    type: integer
                  failed_urls:
                    type: array
                    items:
                      type: string
                  failures:
                    type: array
                    items:
                      type: object
                      properties:
                        url:
                          type: string
                        reason:
                          type: string
                          enum:
                            - unreachable
                            - type_not_allowed
                            - too_large
                            - host_not_allowed
                        message:
                          type: string
              example:
                post:
                  id: 9d3c1f2a-6b4e-4c8a-9f1e-2a7b5c8d0e41
                  post_group_id: 9d3c1f29-e0a1-4b7c-8d2e-5f6a7b8c9d03
                  author:
                    id: 9b1e2d3c-4f5a-4b6c-8d7e-9f0a1b2c3d4e
                    name: Ana Souza
                  content: We just shipped scheduled threads. Here is how they work.
                  media:
                    - id: 9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f
                      path: medias/9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f.jpg
                      url: >-
                        https://media.trypost.it/medias/9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f.jpg
                      type: image
                      mime_type: image/jpeg
                      original_filename: launch.jpg
                      size: 482113
                      meta:
                        width: 1080
                        height: 1350
                        alt_text: Product launch banner
                  status: scheduled
                  schedule_mode: custom
                  scheduled_at: '2026-10-12 14:00:00'
                  published_at: null
                  approval_requested_by: null
                  approval_requested_at: null
                  approved_by: null
                  approved_at: null
                  recurrence: null
                  origin: trypost
                  platforms:
                    - id: 9d3c1f2b-1a2b-4c3d-8e4f-5a6b7c8d9e10
                      platform: x
                      content_type: x_post
                      meta:
                        thread_replies:
                          - text: 2/ Replies publish under the first post.
                            media: []
                      status: pending
                      enabled: true
                      platform_url: null
                      published_at: null
                      error_message: null
                      display_name: TryPost
                      display_username: trypostit
                      display_avatar: >-
                        https://pbs.twimg.com/profile_images/1790000000000000000/avatar_400x400.jpg
                      social_account:
                        id: 9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54
                        platform: x
                        display_name: TryPost
                        username: trypostit
                        status: connected
                        has_posting_schedule: true
                        timezone: America/Sao_Paulo
                        posting_goal: 5
                        max_content_length: 280
                        long_posts: false
                        verified_badge: null
                  labels:
                    - id: 9c0d1e2f-3a4b-4c5d-8e6f-7a8b9c0d1e2f
                      name: Launch
                      color: '#2563EB'
                      created_at: '2026-09-01 10:00:00'
                      updated_at: '2026-09-01 10:00:00'
                  created_at: '2026-10-08 13:20:11'
                  updated_at: '2026-10-08 13:20:11'
                attached_count: 1
                failed_urls:
                  - https://example.com/teaser.mp4
                failures:
                  - url: https://example.com/teaser.mp4
                    reason: unreachable
                    message: Could not fetch media from https://example.com/teaser.mp4.
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/PaymentRequired'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/ValidationError'
        '429':
          $ref: '#/components/responses/TooManyRequests'
components:
  parameters:
    PostId:
      name: post
      in: path
      required: true
      description: Post id. A post of another workspace returns `404`.
      schema:
        type: string
        format: uuid
      example: 9d3c1f2a-6b4e-4c8a-9f1e-2a7b5c8d0e41
  schemas:
    Post:
      type: object
      description: >-
        A post on one channel. Posts created together from several channels are
        independent posts that share a `post_group_id`.
      properties:
        id:
          type: string
          format: uuid
        post_group_id:
          type:
            - string
            - 'null'
          format: uuid
          description: Shared by the posts created in one batch.
        author:
          oneOf:
            - $ref: '#/components/schemas/Person'
            - type: 'null'
        content:
          type:
            - string
            - 'null'
          description: >-
            Post text, stored as sent (posts written in the app hold the
            editor's HTML).
        media:
          type:
            - array
            - 'null'
          items:
            $ref: '#/components/schemas/MediaItem'
        status:
          type: string
          enum:
            - draft
            - pending_approval
            - scheduled
            - publishing
            - published
            - partially_published
            - failed
          description: >-
            `pending_approval` is a post a member who needs approval asked to
            schedule or publish.
        schedule_mode:
          type:
            - string
            - 'null'
          enum:
            - queue
            - custom
            - null
          description: >-
            `queue`: the post holds a slot of the channel's posting schedule.
            `custom`: it is scheduled at its own time.
        scheduled_at:
          type:
            - string
            - 'null'
          description: UTC, format `Y-m-d H:i:s`.
        published_at:
          type:
            - string
            - 'null'
          description: UTC, format `Y-m-d H:i:s`.
        approval_requested_by:
          oneOf:
            - $ref: '#/components/schemas/Person'
            - type: 'null'
          description: Who asked for approval (not always the author).
        approval_requested_at:
          type:
            - string
            - 'null'
          description: UTC, format `Y-m-d H:i:s`.
        approved_by:
          oneOf:
            - $ref: '#/components/schemas/Person'
            - type: 'null'
        approved_at:
          type:
            - string
            - 'null'
          description: UTC, format `Y-m-d H:i:s`.
        recurrence:
          type:
            - object
            - 'null'
          description: Repeat rule, or `null`.
          properties:
            interval:
              type: integer
            frequency:
              type: string
              enum:
                - day
                - week
                - month
                - year
            remaining:
              type:
                - integer
                - 'null'
              description: Repeats left after the next one.
        origin:
          type: string
          enum:
            - trypost
            - network
          description: >-
            `network` for posts imported from the network (published outside
            TryPost).
        platforms:
          type: array
          items:
            $ref: '#/components/schemas/PostPlatform'
        labels:
          type: array
          items:
            $ref: '#/components/schemas/Label'
        created_at:
          type: string
          description: UTC, format `Y-m-d H:i:s`.
        updated_at:
          type: string
          description: UTC, format `Y-m-d H:i:s`.
      examples:
        - id: 9d3c1f2a-6b4e-4c8a-9f1e-2a7b5c8d0e41
          post_group_id: 9d3c1f29-e0a1-4b7c-8d2e-5f6a7b8c9d03
          author:
            id: 9b1e2d3c-4f5a-4b6c-8d7e-9f0a1b2c3d4e
            name: Ana Souza
          content: We just shipped scheduled threads. Here is how they work.
          media:
            - id: 9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f
              path: medias/9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f.jpg
              url: >-
                https://media.trypost.it/medias/9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f.jpg
              type: image
              mime_type: image/jpeg
              original_filename: launch.jpg
              size: 482113
              meta:
                width: 1080
                height: 1350
                alt_text: Product launch banner
          status: scheduled
          schedule_mode: custom
          scheduled_at: '2026-10-12 14:00:00'
          published_at: null
          approval_requested_by: null
          approval_requested_at: null
          approved_by: null
          approved_at: null
          recurrence: null
          origin: trypost
          platforms:
            - id: 9d3c1f2b-1a2b-4c3d-8e4f-5a6b7c8d9e10
              platform: x
              content_type: x_post
              meta:
                thread_replies:
                  - text: 2/ Replies publish under the first post.
                    media: []
              status: pending
              enabled: true
              platform_url: null
              published_at: null
              error_message: null
              display_name: TryPost
              display_username: trypostit
              display_avatar: >-
                https://pbs.twimg.com/profile_images/1790000000000000000/avatar_400x400.jpg
              social_account:
                id: 9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54
                platform: x
                display_name: TryPost
                username: trypostit
                status: connected
                has_posting_schedule: true
                timezone: America/Sao_Paulo
                posting_goal: 5
                max_content_length: 280
                long_posts: false
                verified_badge: null
          labels:
            - id: 9c0d1e2f-3a4b-4c5d-8e6f-7a8b9c0d1e2f
              name: Launch
              color: '#2563EB'
              created_at: '2026-09-01 10:00:00'
              updated_at: '2026-09-01 10:00:00'
          created_at: '2026-10-08 13:20:11'
          updated_at: '2026-10-08 13:20:11'
    Person:
      type: object
      description: A workspace member. Only the id and name are exposed.
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
    MediaItem:
      type: object
      description: A media item as stored on a post.
      properties:
        id:
          type: string
          format: uuid
          description: Media id. Pass it as `media[].id` to reuse the file on another post.
        path:
          type: string
          description: Storage path, `medias/{uuid}.{ext}`.
        url:
          type: string
          format: uri
          description: Public URL of the file.
        type:
          type:
            - string
            - 'null'
          enum:
            - image
            - video
            - document
            - null
          description: '`null` on older items stored without a type.'
        mime_type:
          type:
            - string
            - 'null'
        original_filename:
          type:
            - string
            - 'null'
        size:
          type:
            - integer
            - 'null'
          description: Size in bytes.
        meta:
          $ref: '#/components/schemas/MediaItemMeta'
        source:
          type:
            - string
            - 'null'
          enum:
            - ai
            - unsplash
            - google_drive
            - google_photos
            - canva
            - null
          description: >-
            Where the file came from in the app. Present only on items added
            from one of these sources.
        source_meta:
          type:
            - object
            - 'null'
          description: Details from that source. Present only when the source gave any.
      examples:
        - id: 9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f
          path: medias/9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f.jpg
          url: >-
            https://media.trypost.it/medias/9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f.jpg
          type: image
          mime_type: image/jpeg
          original_filename: launch.jpg
          size: 482113
          meta:
            width: 1080
            height: 1350
            alt_text: Product launch banner
    PostPlatform:
      type: object
      description: 'The post''s destination: one social account and its format and settings.'
      properties:
        id:
          type: string
          format: uuid
          description: Destination id. Use it as `platforms[].id` on `PUT /posts/{post}`.
        platform:
          $ref: '#/components/schemas/Platform'
        content_type:
          oneOf:
            - $ref: '#/components/schemas/ContentType'
            - type: 'null'
        meta:
          type:
            - object
            - array
            - 'null'
          maxItems: 0
          description: >-
            Stored per-network settings (see `PlatformMeta`). Empty settings may
            serialize as an empty array.
        status:
          type:
            - string
            - 'null'
          enum:
            - pending
            - publishing
            - retrying
            - pending_review
            - published
            - failed
            - rejected
            - null
          description: >-
            Publishing state on this network. `retrying` waits for a retry after
            a network limit; `pending_review` and `rejected` come from networks
            that review posts (Google Business).
        enabled:
          type: boolean
        platform_url:
          type:
            - string
            - 'null'
          description: Link to the published post on the network.
        published_at:
          type:
            - string
            - 'null'
          description: UTC, format `Y-m-d H:i:s`.
        error_message:
          type:
            - string
            - 'null'
        display_name:
          type:
            - string
            - 'null'
          description: Account name, kept even after the account is disconnected.
        display_username:
          type:
            - string
            - 'null'
        display_avatar:
          type:
            - string
            - 'null'
        social_account:
          oneOf:
            - $ref: '#/components/schemas/SocialAccount'
            - type: 'null'
          description: >-
            The account, or `null` once it was removed (the `display_*` fields
            keep its name).
    Label:
      type: object
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
        color:
          type: string
          description: Hex color, `#RRGGBB`.
          examples:
            - '#2563EB'
        created_at:
          type: string
          description: UTC, format `Y-m-d H:i:s`.
          examples:
            - '2026-09-01 10:00:00'
        updated_at:
          type: string
          description: UTC, format `Y-m-d H:i:s`.
          examples:
            - '2026-09-01 10:00:00'
    ErrorBody:
      type: object
      properties:
        message:
          type: string
    ValidationErrorBody:
      type: object
      properties:
        message:
          type: string
        errors:
          type: object
          additionalProperties:
            type: array
            items:
              type: string
    RateLimitErrorBody:
      type: object
      properties:
        name:
          type: string
          const: rate_limit_exceeded
        message:
          type: string
          examples:
            - Rate limit exceeded. Please retry after 30 seconds.
    MediaItemMeta:
      type: object
      description: >-
        Editable settings of one media item. Other keys the server measured (for
        example `width`, `height`, `duration`) may also appear in responses.
      properties:
        alt_text:
          type: string
          maxLength: 2000
          description: >-
            Accessibility description. Applies to images; each network truncates
            it to its own cap.
        user_tags:
          type: array
          maxItems: 20
          description: People tagged on an Instagram image.
          items:
            type: object
            required:
              - username
              - x
              - 'y'
            properties:
              username:
                type: string
                pattern: ^@?[A-Za-z0-9._]{1,30}$
                description: Public Instagram username. A leading `@` is dropped.
              x:
                type: number
                minimum: 0
                maximum: 1
                description: Offset from the left edge, 0 to 1.
              'y':
                type: number
                minimum: 0
                maximum: 1
                description: Offset from the top edge, 0 to 1.
        cover_offset_ms:
          type: integer
          minimum: 0
          description: >-
            Video frame used as the cover, in milliseconds from the start.
            Cannot pass the end of the video.
    Platform:
      type: string
      enum:
        - linkedin
        - linkedin-page
        - x
        - tiktok
        - youtube
        - facebook
        - instagram
        - instagram-facebook
        - threads
        - pinterest
        - bluesky
        - mastodon
        - telegram
        - discord
        - google_business
      description: >-
        Network of a social account. `linkedin-page` is a LinkedIn company page,
        `instagram-facebook` an Instagram account connected through a Facebook
        Page.
    ContentType:
      type: string
      enum:
        - instagram_feed
        - instagram_reel
        - instagram_story
        - linkedin_post
        - linkedin_page_post
        - facebook_post
        - facebook_reel
        - facebook_story
        - tiktok_video
        - tiktok_photo
        - youtube_short
        - x_post
        - threads_post
        - threads_ghost_post
        - pinterest_pin
        - pinterest_video_pin
        - pinterest_carousel
        - bluesky_post
        - mastodon_post
        - telegram_post
        - discord_message
        - google_business_post
      description: >-
        Post format on one network. It must belong to the destination's network.
        `GET /content-types` lists the formats of each network with their media
        rules. Instagram and Facebook stories publish no text.
    SocialAccount:
      type: object
      properties:
        id:
          type: string
          format: uuid
        platform:
          $ref: '#/components/schemas/Platform'
        display_name:
          type:
            - string
            - 'null'
        username:
          type:
            - string
            - 'null'
        status:
          type: string
          enum:
            - connected
            - disconnected
            - token_expired
        has_posting_schedule:
          type: boolean
          description: >-
            Whether the channel has posting times. Queueing a post (`queue`)
            needs them.
        timezone:
          type: string
          description: IANA time zone of the channel. Queue slots and recurrence follow it.
        posting_goal:
          type:
            - integer
            - 'null'
          description: Posts per week the channel aims for.
        max_content_length:
          type: integer
          description: >-
            Text limit of this account, in characters. An X account with long
            posts gets 25000.
        long_posts:
          type: boolean
          description: Whether this X account can publish long posts.
        verified_badge:
          type:
            - string
            - 'null'
          enum:
            - blue
            - business
            - government
            - null
          description: >-
            X checkmark; `null` on other networks or unverified accounts. A
            badge alone does not mean long posts: read `long_posts`.
  responses:
    Unauthorized:
      description: >-
        Missing, invalid, revoked or expired API key. Bodies: `Unauthenticated.`
        (no key, or a key that is invalid or revoked), `Token expired.` (past
        its `expires_at`), `Token not found.` and `No workspace selected.` (the
        key is no longer bound to a workspace).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorBody'
          example:
            message: Unauthenticated.
    PaymentRequired:
      description: >-
        TryPost Cloud only: the workspace's account has no active subscription
        or trial. Body: `{"message": "Active subscription required."}`.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorBody'
          example:
            message: Active subscription required.
    Forbidden:
      description: >-
        The request is not allowed. API keys work only for workspace admins (the
        account owner or a member marked as admin): otherwise every request
        returns `Insufficient workspace permissions.`. Other bodies: `Workspace
        access denied.` (the key's user left the workspace) and `Personal access
        token required.` (an MCP OAuth token was sent) and `This action is
        unauthorized.` (the note belongs to another member).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorBody'
    NotFound:
      description: The resource does not exist in this workspace.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorBody'
    Conflict:
      description: >-
        Another change to this post or its channel's queue is in progress.
        Retry.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorBody'
    ValidationError:
      description: Validation failed.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ValidationErrorBody'
    TooManyRequests:
      description: 'Rate limit exceeded. Limits: 60 requests per minute per workspace.'
      headers:
        Retry-After:
          description: Seconds to wait before retrying.
          schema:
            type: integer
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/RateLimitErrorBody'
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: Workspace API key from Settings → API Keys.

````

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