# Import native builds

## OpenAPI Specification

```yaml
openapi: 3.0.1
info:
  title: ''
  description: ''
  version: 1.0.0
paths:
  /be/v1/builds:
    post:
      summary: Import native builds
      deprecated: false
      description: >-
        This endpoint adds a new game build to an existing app. Once imported it
        will automatically generate


        - a new ROCKIT Image
            
        - new ROCKIT Patches if the uploaded game build is not the initial one.
            

        There are two upload modes supported:


        1. ROCKIT Edge Download Request.
            
        2. Client Upload.
            

        Both methods are described below.


        ### File Format


        The game build is expected as an uncompressed tarball
        `native-build.tar`. The generation can be done as follows:


        | **Operating System** | **Tool** |

        | --- | --- |

        | Linux | `cd path/to/gamedir`  <br>`tar cvf /var/tmp/native-build.tar`
        . |

        | Windows | in PowerShell:  <br>`cd path\\to\\gamedir`  <br>`tar -cvf
        C:\\temp\\native-build.tar `. |


        ### ROCKIT Edge Download Request


        If a download URL is provided in the request body (`url`), ROCKIT Edge
        will download the native game build automatically. If the optional body
        request parameter `size` is given, a simple file size check is executed
        after the download has concluded.


        This is the preferred method of importing a native build to ROCKIT Edge.
        The provided URL could be a signed URL with a short lifetime.


        ### Client Upload


        An alternative to the ROCKIT Edge Download Request is the Client Upload
        method. By invoking this endpoint without providing the `url` body
        request parameter a temporary upload URL is returned in the response
        body. Upload the file to this URL using PUT.


        This method can be applied if there is no publically available URL which
        ROCKIT Edge could download from.


        #### Bash


        ``` bash

        #!/bin/bash

        url="https://example.com/upload"  # obtained from "POST /be/v1/builds"

        file_path="path/to/your/native-build.tar"

        curl --fail --silent --show-error -X PUT --upload-file "${file_path}"
        "${url}"

         ```

        #### C/C++


        ``` c

        #include <iostream>

        #include <fstream>

        #include <curl/curl.h>

        int main() {
            CURL *curl;
            CURLcode res;
            const char *url = "https://example.com/upload";  // obtained from "POST /be/v1/builds"
            const char *file_path = "path/to/your/native-build.tar";
            curl_global_init(CURL_GLOBAL_DEFAULT);
            curl = curl_easy_init();
            if(curl) {
                std::ifstream file(file_path, std::ios::binary);
                if (file) {
                    curl_easy_setopt(curl, CURLOPT_URL, url);
                    curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
                    curl_easy_setopt(curl, CURLOPT_READDATA, &file);
                    curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)file.tellg());
                    res = curl_easy_perform(curl);
                    if(res != CURLE_OK)
                        fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
                    else
                        std::cout << "File uploaded successfully" << std::endl;
                    file.close();
                } else {
                    std::cerr << "Failed to open file" << std::endl;
                }
                curl_easy_cleanup(curl);
            }
            curl_global_cleanup();
            return 0;
        }

         ```

        #### Python


        ``` python

        import requests

        url = 'https://example.com/upload'  # obtained from "POST /be/v1/builds"

        file_path = 'path/to/your/native-build.tar'

        with open(file_path, 'rb') as file:
            response = requests.put(url, data=file, headers={'Content-Type': 'application/octet-stream'})
            if response.status_code == 200:
                print('File uploaded successfully:', response.text)
            else:
                print('Error uploading file:', response.status_code, response.text)

         ```

        #### TypeScript


        ``` typescript

        import axios from 'axios';

        import fs from 'fs';

        const url = 'https://example.com/upload';  # obtained from "POST
        /be/v1/builds"

        const filePath = 'path/to/your/native-build.tar';

        const uploadFile = async () => {
          const file = fs.createReadStream(filePath);
          try {
            const response = await axios.put(url, file, {
              headers: {
                'Content-Type': 'application/octet-stream',
              },
            });
            console.log('File uploaded successfully:', response.data);
          } catch (error) {
            console.error('Error uploading file:', error);
          }
        };

        uploadFile();

         ```

        ### Important:

        If certain parameters are incorrect, the import request may appear to
        start successfully but will never finish.



        ### Incorrect Deployment Credentials:


        **Common Problem Indicators:**

        If an app tries to deploy but cannot, it will enter an error state.

        Checking `GET /be/v1/apps` will show that the app is in an error state.

        `GET /be/v1/tasks` can be used to inspect which task failed.


        **Solution:**

        If an app fails to deploy due to incorrect credentials or deployment
        issues, you can resolve it in one of the following ways:


        1. Update the Deployment Credentials & Retry the Task


        - Use `PATCH /deployments` to update the deployment with the correct
        credentials.

        - Use [Retry
        Task](https://edge.api.cloud.rockitplay.com/retry-task-12373263e0.md) to
        trigger the failed task again.

        - If the task now succeeds, the app will no longer be in an error state.

        2. Deregister the Faulty Deployment & Retry the Task


        - Deregister the incorrect deployment(s) from the app with `PATCH
        /apps`.

        - Use [Retry
        Task](https://edge.api.cloud.rockitplay.com/retry-task-12373263e0.md) to
        redeploy the app to all correctly registered deployments.

        - If successful, the app will no longer be in an error state.


        ### Exception Handling

        There are three types of exceptions that may occur during import:


        1. Incorrect URL

        - `GET /be/v1/tasks` shows the failed Download Tar Task (dltar).

        - `GET /be/v1/tasks/{taskId}` reveals:

        httpStatus: HTTP error code indicating failure.

        exitCode: Error code providing further details (e.g., unreachable
        source).

        2. Incorrect sizeBytes Value

        `GET /be/v1/tasks` shows the failed Download Tar Task (dltar).

        `GET /be/v1/tasks/{taskId}` reveals:

        sizeBytesActual: The actual file size.

        sizeBytesExpected: The expected file size (provided in the request).

        3. Invalid Tarball

        `GET /be/v1/tasks` shows the failed Make Raw Task.

        `GET /be/v1/tasks/{taskId}` reveals:

        fileReadFailed:

        filename: Name of the file that failed to be read.

        typeExpected: Expected file type.

        typeDetected: Actual detected file type.


        ### Acknowledging Warnings (Optional)

        These exceptions can be ignored, but if you want to acknowledge them:


        Use `PATCH /be/v1/tasks` to mark them as acknowledged.



        ### Required Permissions


        `apps.update`


        See [Roles](https://edge.api.cloud.rockitplay.com/roles-3618377f0.md)
        for more details.
      tags:
        - ROCKIT Edge - Backend API/Apps
      parameters:
        - name: Authorization
          in: header
          description: >-
            Use the access token obtained from [`POST
            /be/v1/login`](https://edge.api.cloud.rockitplay.com/user-login-org-11611254e0.md)
            or [`POST
            /be/v1/refresh`](https://edge.api.cloud.rockitplay.com/refresh-11630082e0.md)
            as Bearer token. <br>Mutually excluded with `x-rockit-api-key`.
          required: true
          example: Bearer {{_edge_org_admin_access_token}}
          schema:
            type: string
        - name: x-rockit-tenant
          in: header
          description: >
            Unique and immutable tenancy identifier obtained from the ROCKIT
            Edge administrator. <br>Requires `x-rockit-username`,
            `x-rockit-orgname` and `x-rockit-api-key`.
          required: true
          example: '{{EDGE_TENANT_NAME}}'
          schema:
            type: string
        - name: x-rockit-orgname
          in: header
          description: >
            Unique and immutable organization identifier obtained from the
            ROCKIT Edge administrator. <br>Requires `x-rockit-tenant`,
            `x-rockit-username` and `x-rockit-api-key`.
          required: true
          example: '{{EDGE_ORG_NAME}}'
          schema:
            type: string
        - name: x-rockit-username
          in: header
          description: >
            Unique and immutable username which is associated with the apikey.
            <br>Requires `x-rockit-tenant`, `x-rockit-orgname` and
            `x-rockit-api-key`.
          required: true
          example: adminPrincipal
          schema:
            type: string
        - name: x-rockit-api-key
          in: header
          description: >-
            Unique and immutable apikey which is associated with an machine
            user. <br>Mutually excluded with `Authorization` header. Requires
            `x-rockit-tenant`, `x-rockit-username` and `x-rockit-orgname`.
          required: true
          example: '{{_adminPrincipal_apiKey}}'
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                appName:
                  type: string
                  description: Unique and immutable identifier of the app.
                url:
                  type: string
                  description: >-
                    If provided ROCKIT Edge will trigger an automatic download
                    of `native-build.tar` from the provided URL. This is the
                    preferred method of importing native game builds.

                    If this parameter is not provided, the endpoint will return
                    a temporary upload URL to which a client can upload
                    `native-build.tar` using PUT.
                sizeBytes:
                  type: integer
                  minimum: 0
                  maximum: 200000000000
                  description: Required if url is not provided
              x-apidog-orders:
                - appName
                - url
                - sizeBytes
              required:
                - appName
              x-apidog-ignore-properties: []
            example:
              appName: '{{appName}}'
              url: '{{appNativeBuildURL}}'
              sizeBytes: 555
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    description: >-
                      Indicates that the import request for a new native game
                      build was successfully created.
                  message:
                    type: string
                    description: >-
                      A confirmation message (e.g., "import request created")
                      verifying that the native build import process has been
                      initiated.
                required:
                  - status
                  - message
                x-apidog-orders:
                  - status
                  - message
                x-apidog-ignore-properties: []
              examples:
                '1':
                  summary: '200: success with user url'
                  value:
                    status: success
                    message: import request created
                '2':
                  summary: '200: success without pre defined user url'
                  value:
                    status: success
                    message: import request created
                    url: >-
                      https://objectstorage.eu-frankfurt-1.oraclecloud.com/p/cho9yj3x6e-BZmGZasdaslwrgim91Xv8gvopMcKsWynLX98-OWPB9VQkB5ePtyFZtgDBk/n/fr65w9caonhc/b/engine-tar-bucket-test/o/KuhlmannOrg/sushi/0002/native-build.tar
                    expires: 555
                '3':
                  summary: '400: missing-param'
                  value:
                    status: failed
                    error: missing-param
                    message: x-rockit-beauth-token missing
                    detail: header parameter x-rockit-beauth-token is required
                '4':
                  summary: '409: busy'
                  value:
                    status: failed
                    error: busy
                    message: cannot import build
                    detail: the app with name 'sushi' has unfinished tasks
                    tasks:
                      - edgeorga-sushi-0001-1727612854-mkraw
          headers: {}
          x-apidog-name: success
        '400':
          description: ''
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    description: >-
                      Reflects that the creation failed due to one or more
                      invalid or missing parameters in the request.
                  error:
                    type: string
                    description: Contains an error identifier.  (e.g., "invalid-param")
                  message:
                    type: string
                    description: >-
                      Explains the nature of the invalid input (for example,
                      "name invalid").
                  detail:
                    type: string
                    description: >-
                      Offers further context on the error. (e.g., expected
                      pattern for the organization name)
                x-apidog-orders:
                  - 01JQNHED8WRWMW44Z6WFQDJRFN
                required:
                  - status
                  - error
                  - message
                  - detail
                x-apidog-refs:
                  01JQNHED8WRWMW44Z6WFQDJRFN:
                    $ref: '#/components/schemas/Invalid%20Param'
                x-apidog-ignore-properties:
                  - status
                  - error
                  - message
                  - detail
          headers: {}
          x-apidog-name: missing-param
        '401':
          description: ''
          content:
            application/json:
              schema:
                title: ''
                type: object
                properties:
                  status:
                    type: string
                    description: >-
                      Indicates that the organization creation request was
                      rejected because of authentication problems.
                  error:
                    type: string
                    description: Contains an error identifier. (e.g."unauthorized")
                  message:
                    type: string
                    description: >-
                      Provides details such as "invalid token" to help diagnose
                      the failure.
                x-apidog-orders:
                  - 01JQNHFMP9DTC60EY60QYVZCZ7
                required:
                  - status
                  - error
                  - message
                x-apidog-refs:
                  01JQNHFMP9DTC60EY60QYVZCZ7:
                    $ref: '#/components/schemas/unauthorized'
                x-apidog-ignore-properties:
                  - status
                  - error
                  - message
          headers: {}
          x-apidog-name: Unauthorized
        '409':
          description: ''
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                  error:
                    type: string
                  message:
                    type: string
                  detail:
                    type: string
                  tasks:
                    type: array
                    items:
                      type: string
                required:
                  - status
                  - error
                  - message
                  - detail
                  - tasks
                x-apidog-orders:
                  - status
                  - error
                  - message
                  - detail
                  - tasks
                x-apidog-ignore-properties: []
          headers: {}
          x-apidog-name: '409: busy'
        x-200:no user url:
          description: ''
          content:
            application/json:
              schema:
                title: ''
                type: object
                properties: {}
                x-apidog-orders:
                  - 01JQNSD03VV8DEJQHN5HSDQV8T
                x-apidog-refs:
                  01JQNSD03VV8DEJQHN5HSDQV8T:
                    type: object
                    properties: {}
                x-apidog-ignore-properties: []
          headers: {}
          x-apidog-name: no user url
      security: []
      x-apidog-folder: ROCKIT Edge - Backend API/Apps
      x-apidog-status: released
      x-run-in-apidog: https://app.apidog.com/web/project/732774/apis/api-11634363-run
components:
  schemas:
    Invalid Param:
      type: object
      properties:
        status:
          type: string
          description: >-
            Reflects that the creation failed due to one or more invalid or
            missing parameters in the request.
        error:
          type: string
          description: Contains an error identifier.  (e.g., "invalid-param")
        message:
          type: string
          description: >-
            Explains the nature of the invalid input (for example, "name
            invalid").
        detail:
          type: string
          description: >-
            Offers further context on the error. (e.g., expected pattern for the
            organization name)
      required:
        - status
        - error
        - message
        - detail
      x-apidog-orders:
        - status
        - error
        - message
        - detail
      x-apidog-ignore-properties: []
      x-apidog-folder: ''
    unauthorized:
      type: object
      properties:
        status:
          type: string
          description: >-
            Indicates that the organization creation request was rejected
            because of authentication problems.
        error:
          type: string
          description: Contains an error identifier. (e.g."unauthorized")
        message:
          type: string
          description: >-
            Provides details such as "invalid token" to help diagnose the
            failure.
      required:
        - status
        - error
        - message
      x-apidog-orders:
        - status
        - error
        - message
      x-apidog-ignore-properties: []
      x-apidog-folder: ''
  securitySchemes:
    Bearer token:
      type: bearer
      scheme: bearer
      description: >-
        Enter your Access Token. You can obtain this by calling the /be/v1/login
        endpoint. Use the Refresh token to get a new Access token when it
        expires.
servers:
  - url: https://Example-Server.com
    description: Default
security: []

```
