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

# Import uploads from a link

> Confirms asset and quality selections from external-link discovery, starts asynchronous imports, and returns 202 Accepted. Poll GET /uploads/{id} and watch externalSource.state until each upload reaches completed.



## OpenAPI

````yaml https://api.streamloop.app/v1/openapi.json post /uploads/from-link
openapi: 3.1.0
info:
  contact:
    name: Streamloop
    url: https://streamloop.app
  description: >-
    The Streamloop REST API. Authenticate with either an `X-API-Key` header (a
    Streamloop API key, prefix `sl_` — simplest for programmatic clients) or an
    OAuth 2.1 bearer access token (obtain one via https://auth.streamloop.app).
    Collections are cursor-paginated (`limit` + `cursor`, returning `{ data,
    page }`). Errors are RFC 7807 problem documents.
  summary: >-
    Programmatic access to Streamloop — create and control 24/7 loop streams,
    manage media, destinations, playlists, and billing.
  title: Streamloop API
  version: 1.0.0
servers:
  - description: Production
    url: https://api.streamloop.app/v1
security:
  - oauth2: []
  - bearerAuth: []
  - apiKey: []
tags:
  - description: The authenticated user's account.
    name: account
  - description: Credits, usage analytics, invoices, and top-ups.
    name: billing
  - description: Crypto deposit options for topping up credits.
    name: crypto
  - description: Manage streaming destinations (custom RTMP).
    name: destinations
  - description: Service metadata, discovery documents, and batch execution.
    name: meta
  - description: Manage and publish stream playlists.
    name: playlists
  - description: Create, control, schedule, and monitor 24/7 loop streams.
    name: streams
  - description: Upload and manage source media (video/audio).
    name: uploads
paths:
  /uploads/from-link:
    post:
      tags:
        - uploads
      summary: Import uploads from a link
      description: >-
        Confirms asset and quality selections from external-link discovery,
        starts asynchronous imports, and returns 202 Accepted. Poll GET
        /uploads/{id} and watch externalSource.state until each upload reaches
        completed.
      operationId: createUploadFromLink
      parameters:
        - description: >-
            Optional client-generated key. A repeated request with the same key
            replays the original response (within 24h) instead of re-executing —
            safe retries.
          in: header
          name: Idempotency-Key
          required: false
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateUploadFromLinkRequest'
        required: true
      responses:
        '202':
          content:
            application/json:
              schema:
                items:
                  $ref: '#/components/schemas/Upload'
                type: array
          description: >-
            Accepted — the request was accepted for asynchronous processing;
            poll the resource for completion.
          headers:
            RateLimit-Limit:
              description: Requests allowed per window.
              schema:
                type: integer
            RateLimit-Remaining:
              description: Requests remaining in the current window.
              schema:
                type: integer
            RateLimit-Reset:
              description: Seconds until the window resets.
              schema:
                type: integer
        '401':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
          description: Missing or invalid access token.
        '403':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
          description: The token lacks the required scope or access to the resource.
        '404':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
          description: The resource does not exist or is not visible to the caller.
        '422':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
          description: The request body or parameters are invalid.
        '429':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
          description: Rate limit exceeded. Retry after the indicated delay.
          headers:
            Retry-After:
              description: Seconds to wait before retrying.
              schema:
                type: integer
        '502':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
          description: The upstream data service returned an error.
      security:
        - oauth2:
            - streamloop:write
        - bearerAuth: []
        - apiKey: []
components:
  schemas:
    CreateUploadFromLinkRequest:
      properties:
        selections:
          items:
            description: >-
              One asset and quality pair confirmed from ExternalLinkContents,
              optionally narrowed to a

              time range of the source.


              The same asset may appear several times with different ranges:
              each selection produces its

              own upload, so importing two clips of one video (or re-importing a
              different range of a

              video already imported) is a matter of repeating the asset with a
              new range.
            properties:
              assetId:
                type: string
              endSeconds:
                description: >-
                  Import only up to this offset in the source, in seconds. Null
                  (the default) runs to the

                  end. Ranges past the end of the source are truncated by the
                  provider.
                type:
                  - number
                  - 'null'
              preciseCut:
                description: >-
                  Cut exactly at the requested offsets instead of snapping to
                  the nearest keyframes. This

                  re-encodes around each cut, so the import is markedly slower;
                  the default (false) is a

                  stream copy whose start may include up to a few seconds of
                  preceding video. Ignored when

                  no range is given.
                type:
                  - boolean
                  - 'null'
              qualityId:
                type: string
              startSeconds:
                description: >-
                  Import only from this offset in the source, in seconds. Null
                  (the default) starts at the

                  beginning. Must be < endSeconds and < the item's
                  durationSeconds when it is known.
                type:
                  - number
                  - 'null'
            required:
              - assetId
              - qualityId
            type: object
          type: array
        url:
          type: string
      required:
        - selections
        - url
      type: object
    Upload:
      properties:
        createdAt:
          format: date-time
          type: string
        fileSize:
          type:
            - integer
            - 'null'
        id:
          type: string
        mimeType:
          type: string
        name:
          type: string
        type:
          enum:
            - audio
            - video
            - image
          type: string
        uploaded:
          type: boolean
      required:
        - createdAt
        - id
        - mimeType
        - name
        - type
        - uploaded
      type: object
    Problem:
      description: RFC 7807 problem-details error body.
      properties:
        code:
          description: A stable, machine-readable error code.
          type: string
        detail:
          description: A human-readable explanation specific to this occurrence.
          type: string
        status:
          description: The HTTP status code.
          type: integer
        title:
          description: A short, human-readable summary of the problem.
          type: string
        type:
          description: A URI reference identifying the problem type.
          format: uri-reference
          type: string
      required:
        - type
        - title
        - status
        - detail
        - code
      type: object
  securitySchemes:
    oauth2:
      description: OAuth 2.1 authorization-code flow with PKCE.
      flows:
        authorizationCode:
          authorizationUrl: https://auth.streamloop.app/api/auth/oauth2/authorize
          scopes:
            streamloop:billing: Read billing/usage and create top-up links
            streamloop:destructive: Delete streams and destinations
            streamloop:read: Read streams, destinations, playlists, and billing status
            streamloop:write: Create and control streams, destinations, and playlists
          tokenUrl: https://auth.streamloop.app/api/auth/oauth2/token
      type: oauth2
    bearerAuth:
      bearerFormat: JWT
      description: An OAuth 2.1 bearer access token.
      scheme: bearer
      type: http
    apiKey:
      description: >-
        A Streamloop API key (prefix `sl_`), sent in the `X-API-Key` header.
        Create and manage keys in the dashboard. The simplest auth for
        programmatic / agent clients — no OAuth flow required; the key acts as
        its owning user.
      in: header
      name: X-API-Key
      type: apiKey

````