Opera Ads File Upload API

Resumable large-file upload implementing the TUS 1.0.0 protocol, with API-key or HMAC-SHA256 authentication, 4 GB maximum file size, 256 MB chunk ceiling and 7-day session expiry. The upload host is issued per customer by the Opera Ads team.

OpenAPI Specification

opera-file-upload-api-openapi.yml Raw ↑
openapi: 3.0.3
info:
  title: Opera Ads File Upload API
  version: 1.0.0
  description: >-
    Resumable large-file upload for Opera Ads customers, implementing the TUS
    resumable upload protocol 1.0.0 so uploads survive network failures and
    continue from the last confirmed offset. Supports API-key or per-request
    HMAC-SHA256 signature authentication, a 4 GB maximum single file, a 256 MB
    gateway chunk ceiling, a 5 MB minimum chunk (except the final chunk), a
    500 GB per-customer storage quota, and a 7-day upload-session expiry.
    Transcribed by API Evangelist from the public Opera Ads documentation at
    https://doc.adx.opera.com/advertiser/file_upload_api — the host is issued
    per customer by the Opera team, so it is modelled as a server variable.
  contact:
    name: Opera Ads
    url: https://doc.adx.opera.com/
  x-apievangelist-method: generated
  x-apievangelist-source: https://doc.adx.opera.com/advertiser/file_upload_api
servers:
  - url: https://{host}/upload
    description: Upload host issued by the Opera Ads team
    variables:
      host:
        default: upload.example.opera.com
        description: >-
          The upload service host provided by Opera. The documentation writes
          this as https://<service-host>/upload and instructs customers to
          substitute the host given to them.
tags:
  - name: Upload
    description: TUS resumable upload session lifecycle.
  - name: FileManagement
    description: Listing and inspecting uploads.
paths:
  /files:
    options:
      tags: [Upload]
      operationId: getUploadCapabilities
      summary: Discover TUS server capabilities
      description: >-
        Public (unauthenticated) capability discovery. Returns the supported TUS
        versions, enabled extensions and the maximum upload size.
      security: []
      responses:
        '200':
          description: Capability headers
          headers:
            Tus-Version:
              description: TUS protocol versions supported by the server.
              schema:
                type: string
            Tus-Resumable:
              description: Version to use in all subsequent requests.
              schema:
                type: string
            Tus-Extension:
              description: >-
                TUS extensions enabled — creation, creation-with-upload,
                termination, concatenation, creation-defer-length.
              schema:
                type: string
            Tus-Max-Size:
              description: Maximum upload size in bytes (4294967296 = 4 GB).
              schema:
                type: integer
    post:
      tags: [Upload]
      operationId: createUploadSession
      summary: Create an upload session
      description: >-
        Create a TUS upload session. `Upload-Metadata` must carry a base64
        `key` naming the destination path relative to the customer's allocated
        prefix; a leading slash is stripped and path traversal is rejected.
      parameters:
        - name: Tus-Resumable
          in: header
          required: true
          schema:
            type: string
            default: 1.0.0
        - name: Upload-Length
          in: header
          required: true
          description: Total file size in bytes.
          schema:
            type: integer
        - name: Upload-Metadata
          in: header
          required: true
          description: >-
            Comma-separated `name base64value` pairs. `key` is required;
            `filename` is optional and defaults to the basename of `key`.
          schema:
            type: string
      responses:
        '201':
          description: Session created
          headers:
            Location:
              description: Upload session URL used by subsequent PATCH/HEAD/DELETE.
              schema:
                type: string
                format: uri
            Tus-Resumable:
              schema:
                type: string
            Upload-Offset:
              description: Always 0 on creation.
              schema:
                type: integer
        '400':
          description: Missing or invalid Upload-Metadata (missing key, path traversal, empty key)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Missing or invalid authentication
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '413':
          description: Upload-Length exceeds the 4 GB server limit
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
    get:
      tags: [FileManagement]
      operationId: listUploads
      summary: List uploads
      description: List the calling customer's uploads, optionally filtered by status.
      parameters:
        - name: page
          in: query
          description: Page number (1-based).
          schema:
            type: integer
            default: 1
        - name: page_size
          in: query
          description: Records per page (max 100).
          schema:
            type: integer
            default: 20
            maximum: 100
        - name: status
          in: query
          description: 0 = uploading, 1 = complete, 2 = failed, 3 = cancelled.
          schema:
            type: integer
            enum: [0, 1, 2, 3]
      responses:
        '200':
          description: Upload list
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UploadList'
        '401':
          description: Missing or invalid authentication
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /files/{id}:
    parameters:
      - name: id
        in: path
        required: true
        description: Upload session ID (the last path segment of the Location URL).
        schema:
          type: string
    options:
      tags: [Upload]
      operationId: getUploadSessionCapabilities
      summary: Discover TUS capabilities for a session
      security: []
      responses:
        '200':
          description: Capability headers
    patch:
      tags: [Upload]
      operationId: uploadChunk
      summary: Upload a chunk
      description: >-
        Append bytes at `Upload-Offset`. When the returned `Upload-Offset`
        equals `Upload-Length` the upload is complete. Chunks must be at least
        5 MB (except the final chunk) and at most 256 MB.
      parameters:
        - name: Tus-Resumable
          in: header
          required: true
          schema:
            type: string
            default: 1.0.0
        - name: Upload-Offset
          in: header
          required: true
          description: Byte offset at which this chunk starts.
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/offset+octet-stream:
            schema:
              type: string
              format: binary
      responses:
        '204':
          description: Chunk accepted
          headers:
            Upload-Offset:
              description: Total bytes received so far; use as the next chunk's offset.
              schema:
                type: integer
        '400':
          description: Chunk smaller than the 5 MB minimum (non-final chunk)
        '401':
          description: Missing or invalid credentials
        '403':
          description: Upload ID exists but belongs to a different customer
        '404':
          description: Upload ID not found
        '409':
          description: Upload already complete, or Upload-Offset does not match the server offset
        '413':
          description: Chunk exceeds the 256 MB gateway limit
    head:
      tags: [Upload]
      operationId: getUploadOffset
      summary: Get the authoritative resume offset
      description: >-
        Returns the durably-received offset for the session. After an
        interrupted PATCH this call may block for 1–3 minutes while the server
        finalizes; that is expected and is not an error.
      parameters:
        - name: Tus-Resumable
          in: header
          required: true
          schema:
            type: string
            default: 1.0.0
      responses:
        '200':
          description: Current offset
          headers:
            Upload-Length:
              schema:
                type: integer
            Upload-Offset:
              schema:
                type: integer
            Upload-Metadata:
              description: Session metadata, base64 per field; customer-name is server-injected.
              schema:
                type: string
        '401':
          description: Missing or invalid credentials
        '403':
          description: Upload ID exists but belongs to a different customer
        '404':
          description: Upload ID not found
    delete:
      tags: [Upload]
      operationId: cancelUpload
      summary: Cancel an upload
      description: >-
        Idempotent — if the upload is already complete or cancelled the server
        returns 204 without taking further action.
      parameters:
        - name: Tus-Resumable
          in: header
          required: true
          schema:
            type: string
            default: 1.0.0
      responses:
        '204':
          description: Cancelled
        '401':
          description: Missing or invalid credentials
        '403':
          description: Upload ID exists but belongs to a different customer
        '404':
          description: Upload ID not found
    get:
      tags: [FileManagement]
      operationId: getUpload
      summary: Get upload details
      description: >-
        Full record for one upload. For status 0 (uploading), `offset` reflects
        the last completed chunk and is not a safe resume point — use HEAD.
      responses:
        '200':
          description: Upload record
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Upload'
        '401':
          description: Missing or invalid authentication
        '403':
          description: Upload ID exists but belongs to a different customer
        '404':
          description: Upload ID not found
components:
  securitySchemes:
    apiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
      description: >-
        Static API key issued by the Opera team, prefixed `adx_`. Contact Opera
        support to rotate a compromised key.
    hmacAuth:
      type: apiKey
      in: header
      name: X-HMAC-Signature
      description: >-
        Per-request HMAC-SHA256 signature, lowercase hex, over the message
        `{METHOD}\n{PATH}\n{TIMESTAMP}`. Sent alongside `X-HMAC-Key-Id` (format
        `ADX_HMAC_...`) and `X-HMAC-Timestamp` (Unix seconds, ±300s window).
  schemas:
    Upload:
      type: object
      properties:
        upload_id:
          type: string
        filename:
          type: string
        size:
          type: integer
          description: Declared total size in bytes.
        offset:
          type: integer
          description: Bytes recorded by the file-management view (not a resume point).
        status:
          type: integer
          description: 0 = uploading, 1 = complete, 2 = failed, 3 = cancelled.
          enum: [0, 1, 2, 3]
        key:
          type: string
          description: Destination path relative to the customer's storage prefix.
        create_time:
          type: string
          format: date-time
        update_time:
          type: string
          format: date-time
    UploadList:
      type: object
      properties:
        uploads:
          type: array
          items:
            $ref: '#/components/schemas/Upload'
        page:
          type: integer
        page_size:
          type: integer
    Error:
      type: object
      properties:
        error:
          type: string
          description: Human-readable description.
security:
  - apiKeyAuth: []
  - hmacAuth: []