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

# Create a signed R2 upload URL for an app

> Creates or updates an app and returns pre-signed Cloudflare R2 upload URLs for each file



## OpenAPI

````yaml /api-reference/phones.yaml post /apps/create-signed-upload-url
openapi: 3.1.0
info:
  title: Phones
  version: v1
servers:
  - url: https://api.mobilerun.ai
    description: Droidrun Cloud API
security:
  - bearerAuth: []
paths:
  /apps/create-signed-upload-url:
    post:
      tags:
        - Apps Cloud Storage
      summary: Create a signed R2 upload URL for an app
      description: >-
        Creates or updates an app and returns pre-signed Cloudflare R2 upload
        URLs for each file
      operationId: createSignedUploadUrlPublic
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                bundleId:
                  type: string
                  minLength: 1
                  maxLength: 255
                  pattern: ^[a-zA-Z][a-zA-Z0-9_]*(\.[a-zA-Z][a-zA-Z0-9_-]*)+$
                platform:
                  type: string
                  enum:
                    - android
                    - ios
                  default: android
                displayName:
                  type: string
                  minLength: 1
                versionCode:
                  type: number
                versionName:
                  type: string
                  minLength: 1
                country:
                  type: string
                  default: US
                  description: Country code for Search Results
                  example: US
                description:
                  type: string
                iconURL:
                  anyOf:
                    - type: string
                    - type: string
                      format: uri
                    - type: string
                targetSdk:
                  type: number
                developerName:
                  type: string
                sizeBytes:
                  type: number
                files:
                  type: array
                  items:
                    type: object
                    properties:
                      fileName:
                        type: string
                        minLength: 1
                        pattern: ^[^/\\]+\.(apk|xapk|apks)$/i
                      contentType:
                        type: string
                        enum:
                          - application/vnd.android.package-archive
                          - application/octet-stream
                          - application/zip
                      sha256:
                        type: string
                        pattern: ^[a-f0-9]{64}$/i
                    required:
                      - fileName
                      - contentType
                  minItems: 1
              required:
                - bundleId
                - displayName
                - versionCode
                - versionName
                - sizeBytes
                - files
      responses:
        '200':
          description: Signed upload URL created successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  versionId:
                    type: string
                    format: uuid
                    description: App version ID in the database
                  appId:
                    type: string
                    format: uuid
                    description: App ID in the database
                  r2UploadUrls:
                    type: array
                    items:
                      type: object
                      properties:
                        fileName:
                          type: string
                        r2UploadUrl:
                          type: string
                          format: uri
                      required:
                        - fileName
                        - r2UploadUrl
                    description: Pre-signed Cloudflare R2 URLs for uploading app files
                required:
                  - versionId
                  - appId
                  - r2UploadUrls
        '400':
          description: Bad Request
        '401':
          description: Unauthorized
        '500':
          description: Internal Server Error
      x-codeSamples:
        - lang: JavaScript
          source: |-
            import Mobilerun from '@mobilerun/sdk';

            const client = new Mobilerun({
              apiKey: process.env['MOBILERUN_CLOUD_API_KEY'], // This is the default and can be omitted
            });

            const response = await client.apps.createSignedUploadURL({
              bundleId: 'NX0.JB-_-.m-u--_-p.Z1-u_2I.D--_T-_.dzZ-.Wx.L_a8--_.w_D_',
              displayName: 'x',
              files: [
                { contentType: 'application/vnd.android.package-archive', fileName: 'J!Q0Ok0bzJb7.apk/i' },
              ],
              sizeBytes: 0,
              versionCode: 0,
              versionName: 'x',
            });

            console.log(response.appId);
        - lang: Python
          source: |-
            import os
            from mobilerun_sdk import Mobilerun

            client = Mobilerun(
                api_key=os.environ.get("MOBILERUN_CLOUD_API_KEY"),  # This is the default and can be omitted
            )
            response = client.apps.create_signed_upload_url(
                bundle_id="NX0.JB-_-.m-u--_-p.Z1-u_2I.D--_T-_.dzZ-.Wx.L_a8--_.w_D_",
                display_name="x",
                files=[{
                    "content_type": "application/vnd.android.package-archive",
                    "file_name": "J!Q0Ok0bzJb7.apk/i",
                }],
                size_bytes=0,
                version_code=0,
                version_name="x",
            )
            print(response.app_id)
        - lang: Go
          source: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/stainless-sdks/droidrun-cloud-go\"\n\t\"github.com/stainless-sdks/droidrun-cloud-go/option\"\n)\n\nfunc main() {\n\tclient := mobileruncloud.NewClient(\n\t\toption.WithAPIKey(\"My API Key\"),\n\t)\n\tresponse, err := client.Apps.NewSignedUploadURL(context.TODO(), mobileruncloud.AppNewSignedUploadURLParams{\n\t\tBundleID:    \"NX0.JB-_-.m-u--_-p.Z1-u_2I.D--_T-_.dzZ-.Wx.L_a8--_.w_D_\",\n\t\tDisplayName: \"x\",\n\t\tFiles: []mobileruncloud.AppNewSignedUploadURLParamsFile{{\n\t\t\tContentType: \"application/vnd.android.package-archive\",\n\t\t\tFileName:    \"J!Q0Ok0bzJb7.apk/i\",\n\t\t}},\n\t\tSizeBytes:   0,\n\t\tVersionCode: 0,\n\t\tVersionName: \"x\",\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", response.AppID)\n}\n"
        - lang: CLI
          source: |-
            mobilerun-cloud apps create-signed-upload-url \
              --api-key 'My API Key' \
              --bundle-id NX0.JB-_-.m-u--_-p.Z1-u_2I.D--_T-_.dzZ-.Wx.L_a8--_.w_D_ \
              --display-name x \
              --file '{contentType: application/vnd.android.package-archive, fileName: J!Q0Ok0bzJb7.apk/i}' \
              --size-bytes 0 \
              --version-code 0 \
              --version-name x
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: Opaque
      description: Bearer token via Authorization header

````