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

# Create an upload

> Returns a resumable upload URL. `PUT` the file bytes directly to `upload_url` (GCS resumable protocol), then submit a session with `source: { type: "upload", upload_id }`.

Files must be MP4 or MOV, at most 10 GB and 1080p — the same envelope a mobile recording produces.



## OpenAPI

````yaml /openapi.json post /v1/uploads
openapi: 3.1.0
info:
  title: Hooper API
  version: 1.0.0
  description: >-
    Submit basketball game video and receive highlights, shots and per-player
    box scores.


    All endpoints require `Authorization: Bearer hk_prod_…`. Money fields are
    integer **cents**. Timestamps are Unix seconds. Every list — top-level or
    embedded — is `{ object: "list", data, has_more, total_count }`.
servers:
  - url: https://api.hooper.gg
    description: Production (accepts hk_prod_ keys)
security:
  - apiKey: []
tags:
  - name: Uploads
    description: Resumable video uploads to Hooper storage.
  - name: Sessions
    description: >-
      A session is one submitted game and everything the pipeline produced for
      it.
  - name: Billing
    description: Prepaid credits, metered per second of video.
  - name: Webhooks
    description: Signed HTTP callbacks when a session finishes.
  - name: Events
    description: The log of every event Hooper has emitted for your organization.
paths:
  /v1/uploads:
    post:
      tags:
        - Uploads
      summary: Create an upload
      description: >-
        Returns a resumable upload URL. `PUT` the file bytes directly to
        `upload_url` (GCS resumable protocol), then submit a session with
        `source: { type: "upload", upload_id }`.


        Files must be MP4 or MOV, at most 10 GB and 1080p — the same envelope a
        mobile recording produces.
      operationId: createUpload
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateUploadRequest'
      responses:
        '201':
          description: Upload session created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Upload'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
components:
  schemas:
    CreateUploadRequest:
      type: object
      required:
        - size
      properties:
        content_type:
          type: string
          enum:
            - video/mp4
            - video/quicktime
          default: video/mp4
        size:
          type: integer
          description: File size in bytes (max 10 GB).
          example: 2147483648
        filename:
          type: string
    Upload:
      type: object
      properties:
        id:
          type: string
          example: up_3f9a1c2b7e5d4a08
        object:
          type: string
          const: upload
        upload_url:
          type: string
          description: Resumable upload URL. PUT the bytes here.
        content_type:
          type: string
        size:
          type: integer
        expires_in_seconds:
          type: integer
          example: 604800
    ErrorResponse:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - type
            - code
            - message
          properties:
            type:
              type: string
              enum:
                - invalid_request_error
                - authentication_error
                - insufficient_credits
                - rate_limit_error
                - api_error
            code:
              type: string
              example: parameter_invalid
            message:
              type: string
            param:
              type: string
              description: The request field the error refers to, when there is one.
              example: source.url
  responses:
    BadRequest:
      description: Invalid request
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    Unauthorized:
      description: Missing, invalid, revoked or wrong-environment API key
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
  securitySchemes:
    apiKey:
      type: http
      scheme: bearer
      bearerFormat: hk_prod_… / hk_stg_…
      description: >-
        API key issued by Hooper for your organization. Keys are
        environment-tagged: `hk_prod_` keys work against production, `hk_stg_`
        keys against staging.

````