# Introduction

Explore ByteNite Docs to learn how to build, deploy, and run distributed apps—from quick scripts to complex pipelines—at cloud scale.

{% embed url="<https://youtu.be/Jf9UYfrxbAo>" %}

ByteNite’s serverless container platform is built for high-performance teams and developers who need fast startup times, flexible compute, and a simpler path to getting things done—without the headaches of traditional cloud infrastructure.

But we don’t just host containers. We’ve designed a distributed execution fabric that **eliminates cold starts**, **streamlines app architecture**, and gives you **full control over your container environments**—without the overhead of managing infrastructure.

With ByteNite, you can focus on building your app and leave the heavy lifting to us:

* Write your core application and fan-out/fan-in logic in the **programming language you know best**.
* Package your dependencies using any public or private **Docker container image**.
* Define environments and hardware specs with a **lightweight manifest file**.
* Submit jobs that are automatically partitioned, scheduled, and executed across pre-warmed cloud runners—powered by our proprietary distributed execution fabric.<br>

Ready to dive in? This documentation site covers everything you need, from getting started to scaling complex workloads.

## Documentation overview

Our docs are here to guide you—from first steps to advanced workloads. Whether you’re exploring tutorials, learning about core system components, or diving into API references, you’ll find everything you need to build, manage, and scale apps on ByteNite.

{% hint style="info" %}
**Just checking things out?**&#x20;

If you’re unsure whether ByteNite is the right fit for you or your team, start with our [How it Works](/getting-started/how-it-works) guide or read our tutorials—no account needed!
{% endhint %}

### 1. Understanding the workflow

We’ve broken down distributed computing into a few key components to make building and managing apps simpler. To get started, check out our [How it Works](/getting-started/how-it-works) guide, where you’ll dive into the typical processing job's lifecycle and get an overview of each stage, learning example use cases across different data types.

Here’s a quick rundown of a typical setup:

* **Partitioner** – Pre-processes and splits your input data into manageable chunks.
* **App** – Runs the core logic and handles the heavy lifting of your workload.
* **Assembler** – Merges or cleans up the output once processing is complete.

<table data-view="cards"><thead><tr><th></th><th data-hidden data-card-cover data-type="files"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td>Get a step-by-step overview of <strong>ByteNite’s distributed job lifecycle</strong> and see how your workloads run at scale.</td><td><a href="https://1271894904-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC4oKwqyUo55Lw35MjazY%2Fuploads%2FEnD43bvor7tW4EJNTmgu%2Fhow-it-works-cover.webp?alt=media&amp;token=5d9956b3-a43c-40ab-b9b1-39229ce84222">how-it-works-cover.webp</a></td><td><a href="/getting-started/how-it-works">How it Works</a></td></tr></tbody></table>

### 2. Checking out tutorials

If you’re new to ByteNite, a great place to start is with our tutorials. They walk you through real examples, so you can get hands-on experience and see how everything fits together.

<table data-view="cards"><thead><tr><th></th><th data-hidden data-card-cover data-type="files"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td>Get started with <strong>code examples</strong>. Read, learn, replicate.</td><td><a href="https://1271894904-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC4oKwqyUo55Lw35MjazY%2Fuploads%2FjaZGTZURRG284DjkeYvO%2Ftutorials-cover.webp?alt=media&amp;token=f20e9952-3594-4820-9567-04dd5d5885e6">tutorials-cover.webp</a></td><td><a href="/examples/tutorials">Tutorials</a></td></tr></tbody></table>

While it’s tempting to jump straight into building your own applications, we recommend browsing the full system guides first. They’ll help you understand the bigger picture and the components that power ByteNite.

### 3. Taking the next steps: build and launch your apps

Once you’re comfortable with how ByteNite works, the next step is diving into the guides that help you **build, launch, and manage your apps** effectively.

You’ll learn how to structure your workloads using ByteNite’s modular components, connect your data sources, and run distributed jobs. After that, you’ll explore the API that ties everything together—allowing you to automate job launches, manage secrets, access logs, and more.

Head over to the guides below to get the full rundown:

<table data-view="cards"><thead><tr><th></th><th data-hidden data-card-cover data-type="files"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td>Explore ByteNite's Building Blocks, our modular <strong>software components</strong> designed to run your code on our <strong>distributed infrastructure</strong>.</td><td><a href="https://1271894904-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC4oKwqyUo55Lw35MjazY%2Fuploads%2Fd5WqOTUhTciLKabyePul%2Fbuilding-blocks-cover.webp?alt=media&amp;token=6d2e6fde-832d-4590-be50-38ca9b2df77a">building-blocks-cover.webp</a></td><td><a href="/create-with-bytenite/building-blocks">Building Blocks</a></td></tr><tr><td>Learn about our supported <strong>storage integrations</strong>, and connect your data source to ByteNite.</td><td><a href="https://1271894904-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC4oKwqyUo55Lw35MjazY%2Fuploads%2FAiWUp7X8QBBYRZWAWdSA%2Fdata-sources-cover.webp?alt=media&amp;token=4c7a4e24-1e95-4e0d-bc00-3c0dfb0aa9de">data-sources-cover.webp</a></td><td><a href="/launch-with-bytenite/data-sources">Data Sources</a></td></tr><tr><td>Link template, data sources, and parameters to a <strong>job API request</strong> and run your app!</td><td><a href="https://1271894904-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC4oKwqyUo55Lw35MjazY%2Fuploads%2FRUrpQ2N7eckxkhAUuHQu%2Fjobs-cover.webp?alt=media&amp;token=291b9ea7-27d3-499c-9de2-c1ab095ae393">jobs-cover.webp</a></td><td><a href="/launch-with-bytenite/jobs">Jobs</a></td></tr></tbody></table>

***

## Product & services

ByteNite’s serverless computing platform offers APIs and interfaces designed to make app development and workload management smoother at every stage.

As a ByteNite user, you have access to all our services, fully documented right here.

Below, you’ll find our user-facing components, grouped into:

* **UIs** – For interacting with your apps, monitoring jobs, and managing configurations.
* **APIs** – For programmatic access to launch jobs, manage data, and integrate with your workflows.

### UIs

<table data-view="cards"><thead><tr><th></th><th data-hidden data-card-cover data-type="files"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td>Learn <strong>commands</strong> that let you <strong>build and submit apps</strong> to our system.</td><td><a href="https://1271894904-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC4oKwqyUo55Lw35MjazY%2Fuploads%2FA0FUgm522dlVhcCVqtgR%2Fdev-cli-cover.webp?alt=media&amp;token=71c91b04-7351-4ac7-a2a7-8a72b959d379">dev-cli-cover.webp</a></td><td><a href="/create-with-bytenite/bytenite-dev-cli">Developer CLI</a></td></tr><tr><td><strong>Launch jobs</strong> and <strong>manage settings</strong>, including billing and usage from a handy <strong>web platform</strong>.</td><td><a href="https://1271894904-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC4oKwqyUo55Lw35MjazY%2Fuploads%2FC1TZbsiICVOx6Vzis9Fd%2Fcomputing-platform-cover.webp?alt=media&amp;token=e73119b6-6f72-4158-9ad9-34f962ce05bb">computing-platform-cover.webp</a></td><td><a href="/gui/bytenite-computing-platform">ByteNite Computing Platform</a></td></tr></tbody></table>

### APIs

<table data-view="cards"><thead><tr><th></th><th data-hidden data-card-cover data-type="files"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td>Configure and run <strong>jobs</strong>, manage <strong>data sources</strong>, <strong>templates</strong>, and <strong>schemas</strong>.</td><td><a href="https://1271894904-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC4oKwqyUo55Lw35MjazY%2Fuploads%2FDd0BvSh45ppQvIzBNQxM%2Fjobs-api-cover.webp?alt=media&amp;token=337ad9b1-fc4f-4c69-98a9-8bdbca02712b">jobs-api-cover.webp</a></td><td><a href="/api-reference/customer-api">Customer API</a></td></tr><tr><td>Get <strong>credentials</strong>, store <strong>secrets</strong>, and authenticate your requests.</td><td><a href="https://1271894904-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC4oKwqyUo55Lw35MjazY%2Fuploads%2F17tL3fa7YQOIQ402iQvW%2Fauth-api-cover.webp?alt=media&amp;token=10f0bf5b-f64d-4610-a8dd-dec0ce4c8587">auth-api-cover.webp</a></td><td><a href="/api-reference/authentication-api">Authentication API</a></td></tr><tr><td>List and manage your <strong>apps</strong> and <strong>data engines</strong>. Powers the Dev CLI.</td><td><a href="https://1271894904-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC4oKwqyUo55Lw35MjazY%2Fuploads%2FmpGExk1uXhDLaN8aMAJI%2Fdev-api-cover.webp?alt=media&amp;token=e8fd4e37-440f-4ca0-ad71-01be7228ae8d">dev-api-cover.webp</a></td><td><a href="/api-reference/developer-api">Developer API</a></td></tr><tr><td>See your <strong>transaction history</strong>, monitor your <strong>usage</strong> and <strong>current balance</strong>.</td><td><a href="https://1271894904-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC4oKwqyUo55Lw35MjazY%2Fuploads%2F4td4ZoiZLsSmnPmcWE05%2Fwallet-api-cover.webp?alt=media&amp;token=25a759ce-627d-4824-94d2-edb38d18a413">wallet-api-cover.webp</a></td><td><a href="/api-reference/wallet-api">Wallet API</a></td></tr></tbody></table>


# How it Works

Job lifecycle: an overview of ByteNite's end-to-end workflow

<figure><img src="https://1271894904-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC4oKwqyUo55Lw35MjazY%2Fuploads%2FFDjWZEIJRIkDOmL7r1vH%2FUser%20Workflows%20-%20Mid-Level%20Overview.png?alt=media&amp;token=090a89c4-dccf-439d-ab86-a39ec7c0f15b" alt=""><figcaption></figcaption></figure>

At ByteNite, a typical job follows this lifecycle:

1. **Launch Phase**: The customer initiates a job via the ByteNite API, specifying the data source and configuration details. The system pulls data from various cloud storage services (AWS S3, GCP, Azure, etc.).
2. **Create Phase**: This encompasses three stages:
   * **Partitioner**: The partitioner ingests the raw data, pre-processes it if necessary, and fans it out into independent chunks for parallel execution.
   * **App**: Each chunk is processed independently by the user-defined App, running the core logic (e.g., AI inference, media transcoding, data transformation).
   * **Assembler**: The assembler collects the results from each parallel execution, performs optional post-processing, and generates the final output.
3. **Launch Phase (continued)**: Once the job completes, the assembled output is written back to the designated data destination (cloud storage), and the job status is finalized.

This modular flow ensures scalability, fault tolerance, and flexibility, letting you focus on building impactful applications without worrying about the underlying infrastructure.

***

## 📦 Data pre-processing and task fan-out

Many applications require a pre-processing step to clean, filter, or split data into manageable chunks before core processing. ByteNite’s **Partitioning Engine** handles this pre-processing and task fan-out, distributing your workload across multiple parallel workers.

Whether you’re working with structured tables, unstructured media files, or semi-structured logs, ByteNite’s partitioners support a variety of fan-out strategies.

### Examples of task fan-out use cases

| Data Type                | Partitioning Engine Examples                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Structured Data**      | <p>- Sharding by row/item count<br>- Sharding by date range or key</p>                                                                                                                                                                                                                                                                                                                                                                                                        |
| **Semi-Structured Data** | <p>- Key extraction and object fan-out<br>- Log file splitting by timestamp</p>                                                                                                                                                                                                                                                                                                                                                                                               |
| **Unstructured Data**    | <p><strong>Text/Code</strong><br>- Document splitting by section or size<br>- Codebase sharding by file/module<br><br><strong>Image</strong><br>- Image tiling<br>- Batch splitting for inference<br><br><strong>Audio</strong><br>- Time-based audio chunking<br>- Silence detection-based chunking<br>- Language segment splitting<br><br><strong>Video</strong><br>- Frame-based video chunking<br>- Scene detection-based chunking<br>- Resolution-specific splitting</p> |
| **Any**                  | <p>- Task replication for redundancy<br>- Passthrough (no fan-out)</p>                                                                                                                                                                                                                                                                                                                                                                                                        |

If your workflow doesn’t require splitting data into tasks, you can use a passthrough partitioner to skip the fan-out phase.

***

## 🧠 Core Task Execution

The **App** represents the core logic of your distributed job—this is where the heavy lifting happens. Whether it’s AI inference, media rendering, data transformation, or scientific computation, Apps execute these workloads in parallel across the data chunks produced by the partitioner.

You bring your container image with the necessary code and dependencies; ByteNite handles the rest: container orchestration, retries, scaling, and resource management.

### Examples of core processing use cases

| Category                 | Example Workloads                                                                                                                                |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| **AI/ML**                | <p>- Model inference (e.g., object detection, language models)<br>- Model training on distributed datasets<br>- Feature extraction pipelines</p> |
| **Data Processing**      | <p>- ETL (Extract, Transform, Load) operations<br>- Batch processing of logs or events<br>- Data anonymization or sanitization</p>               |
| **Media Processing**     | <p>- Audio transcription<br>- Image classification or enhancement<br>- Video transcoding or thumbnail generation</p>                             |
| **Scientific Computing** | <p>- Genomic sequence analysis<br>- Simulation workloads<br>- Complex mathematical computations</p>                                              |
| **Other**                | <p>- Web scraping at scale<br>- Document parsing and conversion<br>- File format conversions</p>                                                 |

***

## 📥 Task Fan-In and Data Post-Processing

After core processing, results from each task may need to be collected and aggregated. The **Assembling Engine** performs this fan-in and post-processing, allowing you to organize or transform the results before outputting them to the final destination.

This stage can be as simple as zipping files together or as complex as reassembling a video stream.

### Examples of task fan-in use cases

| Data Type                | Assembling Engine Examples                                                                                                                                                                                                                                                                                                                                                                             |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Structured Data**      | <p>- Data merging based on keys<br>- Sorted concatenation of CSV/JSON files</p>                                                                                                                                                                                                                                                                                                                        |
| **Semi-Structured Data** | <p>- Log file aggregation<br>- Schema validation and merging</p>                                                                                                                                                                                                                                                                                                                                       |
| **Unstructured Data**    | <p><strong>Text/Code</strong><br>- Document stitching (e.g., combining chapters)<br>- Codebase reassembly<br><br><strong>Image</strong><br>- Batch packaging of images<br>- Mosaic creation from tiles<br><br><strong>Audio</strong><br>- Concatenation of audio chunks<br>- Index-based reassembly<br><br><strong>Video</strong><br>- Video stream stitching<br>- Scene-ordered assembly of clips</p> |
| **Any**                  | <p>- File zipping<br>- Passthrough (no fan-in)</p>                                                                                                                                                                                                                                                                                                                                                     |

If no post-processing is required, a passthrough assembler can output task results directly.


# Onboarding

Get all you need to begin running workloads on ByteNite and doing some Byte-magic!

***

## 👤 Create an account

1. **Get an access code**\
   Currently, our platform is in beta and you'll need an access code to create an account. If you have one, use it when required during the sign-up process. Otherwise, you can [Request an Access Code](https://bytenite.com/get-access).
2. **Sign up on Computing Platform**\
   To create an account on ByteNite, follow this link and fill out the form with your contact info and your access code: [Sign Up for ByteNite](https://idp.bytenite.com/login?auth_mode=signup).

***

## 💳 Add a payment method

Having an account is sufficient for creating apps and start playing around with ByteNite. However, once your credits are over you’ll need an active billing account to keep launching jobs. Follow the steps below to add a payment method to your account and activate it.

1. **Access your Billing page**\
   After registering and logging in, go to <https://app.bytenite.com/billing> or navigate to the **Billing** page on the sidebar.
2. **Add a payment method**\
   Locate the Payment Info card an navigate to the Customer Portal. Follow the steps to add a payment method to your account.

NOTE: Your payment information will be stored for manual top-ups as well as automatic top-ups triggered by the end of the current billing cycle. Make sure you have enough funds to cover your previous billing cycle's costs to avoid service interruptions.

***

## 🪙 Redeem ByteChips

If you have a coupon, you can redeem it on your billing page to add ByteChips to your balance.

1. **Access your Billing page**: \
   After registering and logging in, go to <https://app.bytenite.com/billing> or navigate to the **Billing** page on the sidebar.

* **Redeem a coupon**: \
  Go to the Account Balance card and click on "**Redeem**". Enter your coupon code in the corresponding field and complete the process. Ensure the amount has been added to your balance; refresh the page if needed.

We'd love to get you started with free credits to test our platform. If you haven't received free ByteChips upon signing up, [send us a message,](https://bytenite.com/info) and we'll grant you some.

***

## 🔐 Get an API key

For programmatic access to our API, you'll need an API key linked to your account. You can have multiple keys, each meant for a specific integration. Follow these steps to get a key:

1. **Access your profile**\
   After registering and logging in, go to <https://app.bytenite.com/profile> or click on your profile avatar located in the top right corner of the webpage.
2. **Create a new API key**\
   On your profile page, locate and click the '**New API Key**' button or link.
3. **Configure your API key settings**\
   Provide a descriptive name for your API key, choose its validity duration, and enter the confirmation code sent to your email. After filling out the necessary details, click the 'Generate API Key' button.
4. **Copy your API key**\
   Once generated, immediately copy your API key and securely store it. Treat your API key with the same security precautions as a password.

{% hint style="warning" %}
**One-time API key access**

Please note that for security reasons your API key will only be visible and copyable right after you've generated it. Be sure to copy and securely store it immediately.

*Note: The "key ID" is merely an identifier and differs from the actual key.*
{% endhint %}

6. **Managing your API keys**\
   If your key is no longer needed or is compromised, return to the API section in your profile. Find the key and click 'Revoke' to invalidate it.

***

## 🔑 Get an access token

An access token is required to authenticate all requests to the ByteNite API, except for OTP and access token requests.&#x20;

To request an access token, send a request to the [Access Token](/api-reference/authentication-api/access-token#access_token) endpoint using your API key.

Access tokens have a default duration of 3600 seconds (i.e., 1  hour). Once expired, you must request a new one.&#x20;

***

## 🛠️ Set up development tools

Here are some recommended tools to get started with ByteNite's[How it Works](/getting-started/how-it-works#product-and-services).

1. **Download & set up ByteNite Dev CLI:**

{% content-ref url="/pages/UbCTmRkbiAGVWh6gCK1I" %}
[Developer CLI](/create-with-bytenite/bytenite-dev-cli)
{% endcontent-ref %}

2. **Set up ByteNite API:**

<details>

<summary><strong>Create a Postman collection from ByteNite's OAS</strong></summary>

Postman is a popular API development tool that simplifies API testing, debugging, and collaboration. It allows developers to organize API requests into collections for easy management and execution. With Postman, you can quickly import ByteNite's OpenAPI Specifications (OAS), generate pre-formatted API requests, and start interacting with our APIs without the need to write code.

Below is a setp-by-step guide to set up Postman and load ByteNite's API specification:

1. **Launch Postman**\
   Download [Postman](https://www.postman.com/) on your device or access the web app from your browser. Create a free account and log in to start using the platform.
2. **Import ByteNite's OpenAPI Specification**
   * Click the **"Import"** button at the top-left corner of the Postman interface.
   * In the **Import modal**, switch to the **"Link"** tab.
   * Paste one of ByteNite's Swagger JSON links into the URL field:
     * **Jobs API**: [`https://api.bytenite.com/v1/customer/docs/swagger.json`](https://api.bytenite.com/v1/customer/docs/swagger.json)
     * **Auth API**: [`https://api.bytenite.com/v1/auth/docs/swagger.json`](https://api.bytenite.com/v1/customer/docs/swagger.json)
     * **Dev API**: [`https://api.bytenite.com/v1/dev/docs/swagger.json`](https://api.bytenite.com/v1/customer/docs/swagger.json)
   * Click **"Continue"**.
3. **Confirm and Create the Collection**
   * Postman will analyze the Swagger JSON and prompt you to confirm the import.
   * Ensure one of the options "Postman Collection" or "OpenAPI 2.0 with a Postman Collection" are selected.
   * Click **"Import"** to generate the collection.
   * Repeat for each Swagger JSON file.
4. **Review the Imported Collection**
   * Navigate to the **Collections** tab in Postman.
   * Locate the newly created collections (`ByteNite jobs API`, `ByteNite auth API`, `ByteNite dev API`).
   * Expand the collection to see the organized endpoints and methods.
5. **Configure Environment Variables (Optional)**\
   Environment variables in Postman are useful for storing values like API keys, names, and IDs that you frequently use in your requests. By using environment variables, you can manage these values centrally and reuse them across multiple requests.
6. **Test the API**
   * Select an endpoint from the collection.
   * Add the necessary headers, body, or parameters as specified in ByteNite's documentation.
   * Click **"Send"** to execute the request and view the response.
   * That’s it! You’ve successfully set up ByteNite’s API collections in Postman.&#x20;

**Additional Tips**

* **Authentication**: ByteNite APIs require authentication (Bearer tokens). Set up the required auth details under the **Authorization** tab for the collection or individual requests.
* **Collaboration**: Share the imported collection with your team by clicking **"Share Collection"**.
* **Documentation**: Use Postman’s **Documentation** feature to add notes or examples to requests for easy reference.

</details>


# Tutorials

Welcome! We have cooked up a few tutorials to help you get started on ByteNite.&#x20;

<table data-view="cards"><thead><tr><th></th><th data-type="content-ref"></th><th></th><th data-hidden data-card-target data-type="content-ref"></th><th data-hidden data-card-cover data-type="image">Cover image</th><th data-hidden></th></tr></thead><tbody><tr><td><h2>Hello World</h2></td><td><a href="/examples/tutorials/hello-world">Hello, World!</a></td><td>Build a simple "Hello, World" app on ByteNite.</td><td><a href="/examples/tutorials/hello-world">Hello, World!</a></td><td><a href="https://1271894904-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC4oKwqyUo55Lw35MjazY%2Fuploads%2FT6kogyHfYQ2LjLa3xDxP%2FAdobeStock_490529301%20Large.jpeg?alt=media&amp;token=8fe51041-2ec6-4fef-b4f4-34d7af4c7f08">AdobeStock_490529301 Large.jpeg</a></td><td><em><mark style="color:purple;">~15min</mark></em></td></tr><tr><td><h2>Image Generation</h2></td><td><a href="https://github.com/ByteNite2/img-gen-diffusers">https://github.com/ByteNite2/img-gen-diffusers</a></td><td>Run a distributed image generation job using Pytorch and Diffusers on ByteNite.</td><td><a href="https://github.com/ByteNite2/img-gen-diffusers">https://github.com/ByteNite2/img-gen-diffusers</a></td><td><a href="https://1271894904-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC4oKwqyUo55Lw35MjazY%2Fuploads%2F6Jv2DkOgo4vbUOB35ek1%2Fu7431618293_A_cover_for_a_developer_guide_called_Image_Genera_8de505b4-40c9-40df-87ec-b3864f0a9c2f_0.png?alt=media&amp;token=0864a1cb-cfe1-47a3-99f2-e1b5513bd370">u7431618293_A_cover_for_a_developer_guide_called_Image_Genera_8de505b4-40c9-40df-87ec-b3864f0a9c2f_0.png</a></td><td><em><mark style="color:purple;">~45min</mark></em></td></tr><tr><td><h2>LLM Serving</h2></td><td><a href="https://github.com/ByteNite2/llm-serving">https://github.com/ByteNite2/llm-serving</a></td><td>Serve a quantized 17B Llama 4 Scout model using <code>llama-cpp-python</code> on ByteNite. </td><td></td><td><a href="https://1271894904-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC4oKwqyUo55Lw35MjazY%2Fuploads%2F04tY56hsW89KWDrE1k33%2Fllm-serving-llama-meta-ai.webp?alt=media&amp;token=06ae9aa9-d5af-4883-812d-4e4f64865c1c">llm-serving-llama-meta-ai.webp</a></td><td></td></tr><tr><td><h2>Web Scraping</h2></td><td><a href="https://github.com/ByteNite2/web-scraper">https://github.com/ByteNite2/web-scraper</a></td><td>Scrape Amazon product data at scale using Playwright, extracting titles, prices, and buyer counts on ByteNite.</td><td></td><td><a href="https://1271894904-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC4oKwqyUo55Lw35MjazY%2Fuploads%2FL0QnvKcdXJhXVm8Zi0Oe%2Fweb-crawling-spider.webp?alt=media&amp;token=d1899e5d-7aac-4e36-a666-11348f17149d">web-crawling-spider.webp</a></td><td></td></tr></tbody></table>

<br>


# Hello, World!

The goal of this tutorial is to build a simple ByteNite app that outputs the string "Hello, World!" to a file. Use this tutorial if you're new to ByteNite and want to have a quick sense of the workflow.

| Duration | Difficulty                                  | Prerequisites                                                                                                                                                                                                                                                                                       |
| -------- | ------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| \~15 min | <mark style="color:green;">Very Easy</mark> | <ul class="contains-task-list"><li><input type="checkbox" checked><a data-mention href="/getting-started/onboarding">/pages/UpkXIWmOKjGcqBdlUu1Y</a></li><li><input type="checkbox" checked><a data-mention href="/create-with-bytenite/bytenite-dev-cli">/pages/UbCTmRkbiAGVWh6gCK1I</a></li></ul> |

***

{% stepper %}
{% step %}

### Download sample app

Run the `app new` command in your terminal to create an app directory locally named "hello-world":

```bash
bytenite app new hello-world
```

Check that a new directory named "hello-world" was indeed created at your base path:

```
ls
```

{% endstep %}

{% step %}

### Write the main script

Locate your pre-generated Python entry point  (`./hello-world/app/main.py)` and add the code to the file.

We'll make the app perform a few simple steps:

* Read a string from the input text file (chunk).
* Convert the string to a case matching the input parameter 'case'.
* Write the result to a text file in the task results directory.

{% code title="main.py" fullWidth="true" %}

```python
if __name__ == '__main__':
    print("Python task started")
    result_path = os.path.join(task_results_dir, 'processed_chunk.txt')
    try:
         # 1. Reading Inputs
    
        # Expect a text file to be passed by the partitioner
        with open(chunk_path, 'r', encoding="utf-8") as infile:
            my_string = infile.read()

        # 2. Handling Parameters
        
        # Expect the job parameters to have a key named 'case', and the options to be "upper", "lower", and "title"
        case = app_params['case']

        # 3. Developing the Core Functionality
        
        # Process the string based on the case parameter
        if case == "upper":
            my_string = my_string.upper()
        elif case == "lower":
            my_string = my_string.lower()
        elif case == "title":
            my_string = my_string.title()
        else:
            my_string = my_string
        
        # 4. Saving Outputs

        # Save the string directly into a text file to the default task results directory
        with open(os.path.join(task_results_dir, "hello_world_processed.txt"), 'w', encoding="utf-8") as outfile:
            outfile.write(my_string)

    except Exception as e:
        print("Python exception: ", e)
        raise e

```

{% endcode %}
{% endstep %}

{% step %}

### Check your manifest and template files

The manifest and template files are automatically generated and located in your `hello-world` directory. Ensure they contain the correct configurations as shown below.&#x20;

Note: We're using passthrough partitioning and assembling engines in this template, so there's no need to configure these components.

{% code title="manifest.json" %}

```json
{
  "name": "hello-world",
  "version": "0.1",
  "platform": "docker",
  "description": "An app named hello-world",
  "entrypoint": "main.py",
  "platform_config": {
    "container": "python:latest"
  },
  "device_requirements": {
    "min_cpu": 2,
    "min_memory": 2
  }
}
```

{% endcode %}

{% code title="template.json" %}

```json
{
  "id": "hello-world-template",
  "description": "A template for hello-world",
  "app": "hello-world",
  "partitioner": "passthrough",
  "assembler": "passthrough"
}
```

{% endcode %}
{% endstep %}

{% step %}

### Submit and activate your app

Upload the content of your app:

```bash
bytenite app push hello-world
```

Activate your app to make it accept jobs:

```
bytenite app activate hello-world
```

Now, check your app's details and status by running the command:

```
bytenite app get hello-world
```

Finally, ensure that your template was correctly uploaded—you will need that for running jobs.&#x20;

```
bytenite template get hello-world-template
```

{% endstep %}

{% step %}

### Launch a job with 'hello-world-template'

Let's launch a job with your new `hello-world-template`  and test your app.

Send a POST request to the Job [Create](/api-reference/customer-api/jobs/create) endpoint, including the following fields in the request body:

<table><thead><tr><th width="174.77734375">Key</th><th>Value</th></tr></thead><tbody><tr><td><code>templateId</code></td><td><code>hello-world-template</code></td></tr><tr><td><code>dataSource</code></td><td><pre class="language-json"><code class="lang-json">{
<strong>    "dataSourceDescriptor": "url",
</strong>    "params": {
        "@type": "type.googleapis.com/bytenite.data_source.HttpDataSource",
        "url": "https://storage.googleapis.com/video-test-public/hello-world-I.txt"
    }
}
</code></pre></td></tr><tr><td><code>dataDestination</code></td><td><pre class="language-json"><code class="lang-json">{
    "dataSourceDescriptor": "bucket"
}
</code></pre></td></tr><tr><td><code>params</code></td><td><pre class="language-json"><code class="lang-json">{
    "app": {
        "case": "upper"
    }
}
</code></pre></td></tr></tbody></table>

Then, launch your job and check the results.

Here's a Postman collection that you can use to run your Hello World job:

{% embed url="<https://www.postman.com/bytenite-team/workspace/bytenite-api-demos/collection/36285584-17ffcb17-3596-4425-89a1-21b85b238a1e?action=share&active-environment=36285584-29ed148e-d761-4e24-9d58-0175af333612&creator=36285584>" %}
{% endstep %}
{% endstepper %}


# Building Blocks

Overview of ByteNite's core components and functionalities

ByteNite's building blocks are designed to help you structure your distributed workloads into modular, reusable components. These components—Partitioners, Apps, and Assemblers—let you focus on your core logic without worrying about the complexities of distributed execution, fault tolerance, retries, or logging. We've got that covered.

At a high level, ByteNite breaks down a distributed job's lifecycle into three phases:

1. **Partitioning Engine**: Handles input downloading, pre-processing, and task creation.
2. **App**: Executes the core logic for each individual task.
3. **Assembling Engine**: Collects and merges the results from individual tasks.

Each component is fully customizable and versionable, enabling you to build flexible pipelines that fit your specific needs.&#x20;

Explore the following guides to learn how to develop your own ByteNite Apps, Partitioning Engines, and Assembling Engines to create distributed workflows tailored to your needs.

<table data-view="cards"><thead><tr><th></th><th data-hidden data-card-target data-type="content-ref"></th><th data-hidden data-card-cover data-type="files"></th></tr></thead><tbody><tr><td><strong>Apps</strong> let you submit code to run on ByteNite's infrastructure.</td><td><a href="/create-with-bytenite/building-blocks/apps">Apps</a></td><td><a href="https://1271894904-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC4oKwqyUo55Lw35MjazY%2Fuploads%2FHg2SC7CpY3IXK09IZhVP%2Fapps-card-cover.png?alt=media&amp;token=5fc68ac1-e2a5-496d-b785-c9d85e748baf">apps-card-cover.png</a></td></tr><tr><td>Build a <strong>Data Partitioning Engine</strong> to tell your app how to pre-process input data. </td><td><a href="/create-with-bytenite/building-blocks/partitioning-engines">Partitioning Engines</a></td><td><a href="https://1271894904-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC4oKwqyUo55Lw35MjazY%2Fuploads%2FmduuaO9timFPBTSCg0n1%2Fpartitioning-engines-card-cover.png?alt=media&amp;token=beb05358-79bc-46de-a28f-e65e6080da87">partitioning-engines-card-cover.png</a></td></tr><tr><td>Add a <strong>Data Assembling Engine</strong> to define chunk merging logic.</td><td><a href="/create-with-bytenite/building-blocks/assembling-engines">Assembling Engines</a></td><td><a href="https://1271894904-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC4oKwqyUo55Lw35MjazY%2Fuploads%2FDVl0qD44TdChuYEhE4qb%2Fassembling-engines-card-cover.png?alt=media&amp;token=e750e722-a674-464e-b298-dd118a3def23">assembling-engines-card-cover.png</a></td></tr><tr><td>Use <strong>Job Templates</strong> to harmonize versions across apps and data engines.</td><td><a href="/create-with-bytenite/building-blocks/job-templates">Job Templates</a></td><td><a href="https://1271894904-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC4oKwqyUo55Lw35MjazY%2Fuploads%2FeN7mqAPDQEfDCwnGs18O%2Fjob-templates-card-cover.png?alt=media&amp;token=e0ad5346-db5f-4482-a2a4-d374604ffeb8">job-templates-card-cover.png</a></td></tr></tbody></table>


# Apps

An **App** is a versioned program that lets you run code on ByteNite.

Apps can be simple—just a single function—or complex systems with multiple libraries and functions.

This guide walks through the structure of an app’s directory and explains where (and how) to write your code so it integrates smoothly into a ByteNite app.

## 📁 App directory overview

To create a new `app` directory in your local environment, execute the following [Developer CLI](/create-with-bytenite/bytenite-dev-cli) command:

```bash
bytenite app new [app_name]
```

A sample folder with pre-populated files and fields will be generated at your current path:

<pre><code>/[app_name]
├── app
│   ├── main.*
│   └── [scripts/libraries]
├── manifest.json
├── template.json
<a data-footnote-ref href="#user-content-fn-1">└── schema.json</a>
</code></pre>

**Directory Structure**:

* `app/`\
  Contains your application’s entry point (`main.*`), plus any additional scripts or libraries.\
  See: [#develop-the-main-script](#develop-the-main-script "mention").
* `manifest.json`\
  Holds configurations, details, and app requirements.\
  See: [#configure-app-settings-manifest.json](#configure-app-settings-manifest.json "mention").
* `template.json`\
  Defines your job template, which ties together your building blocks into a single configuration. This template can be optionally submitted with your app.\
  Learn more: #[Job Templates](/create-with-bytenite/building-blocks/job-templates).&#x20;
* `schema.json`\
  Provides input parameter validation for your app using a JSON schema definition.\
  See:[#optional-require-parameter-validation-schema.json](#optional-require-parameter-validation-schema.json "mention").

***

## 🔧 Configure app settings: `manifest.json`

The **manifest.json** file holds the core details of your app—things like platform configuration, hardware requirements, the app’s name, and version.

Here’s a sample manifest:

{% code title="manifest.json - full example" %}

```json
{
  "name": "my-first-stable-diffusion-app",
  "version": "0.4",
  "description": "A stable diffusion app using HuggingFace's diffusers",
  "platform": "docker",
  "entrypoint": "main.py",
  "platform_config": {
    "container": "huggingface/diffusers-pytorch-cuda:latest",
    "private_image": true,
    "username": "alex_rivers6241",
    "token":"dckr_pat_HgNOmERVLDm1YBSvAJELJeGOOAM",
    "secrets":["MY_GCS_SECRET"]
  },
  "device_requirements": {
    "min_cpu": 2,
    "min_memory": 2,
    "gpu": ["NVIDIA A100-SXM4-40GB", "NVIDIA GeForce RTX 4090"] 
  }
}
```

{% endcode %}

**How the manifest works**

The manifest defines key settings your app depends on, including:

* Platform configuration (e.g., Docker container + data source details)
* Hardware requirements (e.g., minimum CPU and memory)
* App metadata (name, version, description)

Since many apps rely on specific hardware or container setups, tweaking this file to align with your app’s needs is essential for reliable performance.

The following sections dive deeper into app versioning, platform settings, and hardware requirements—all centered around how to define them in your manifest.json.

***

### App versioning

Each app is identified by a `name` and a `version`, following the semantic versioning format "major.minor".&#x20;

* **Unlimited versions**: You can store and activate unlimited versions of your app, provided that each one has a unique `(name, version)` pair.
* **Uploading a new version**: Uploading an app with a new `(name, version)` combination will create a new, independent record. This is helpful if you need to maintain separate versions for testing, staging, or production.
* **Updating versions**: Uploading an app with an existing `(name, version)` pair will overwrite the current version with your updated code and configurations.

Use the `name` and `version` fields in the manifest to manage app uploads and ensure consistency across your deployments:

<details>

<summary><code>name</code>  <em>string</em></summary>

**Description:**

The human-readable name of your app. This acts as the app’s identifier.

**Supported Format:**

* Alphanumeric characters, dashes (-), and underscores (\_)
* Max length: 64 characters

**Example:**

`"my-first-stable-diffusion-app"`

</details>

<details>

<summary><code>version</code>  <em>string</em></summary>

**Description:**

A semantic version for managing updates.

**Supported Format:**

`"[major].[minor]"`&#x20;

* `major`  *int*
* `minor`  *int*

**Example:**

`"0.4"`

</details>

***

### Platform & hardware requirements

ByteNite supports containerized workloads by integrating with Docker images from [Docker Hub](https://hub.docker.com). Docker lets you package your app’s dependencies, libraries, and runtime into a single, portable container—so your app runs consistently across environments.

To configure your app’s environment:

* Define the **platform** type and the container image using the `platform` and `platformConfig` fields in your manifest.
* Set your app’s minimum **hardware requirements** (like CPU and memory) using the `deviceRequirements` field.

These settings ensure your app runs in the right environment with the right resources. Learn more below.

#### Platform Configs

To run your app on ByteNite, use the `platform` and `platformConfig` fields in the manifest to define the Docker container image your app should use.

The container image must be either publicly accessible or include the proper credentials if it’s private. It can be hosted on Docker Hub or any compatible container registry.

While there are many ready-to-use images, most apps require custom images tailored to specific dependencies, environment variables, or system configurations. Defining this ensures your app runs exactly how you need it.

<details>

<summary><code>platform</code>  <em>string</em></summary>

**Description:**

Specifies the platform your app will run on.

**Supported Values:**

* `["docker"]`

</details>

<details>

<summary><code>platformConfig</code>  <em>object</em></summary>

**Description:**

Contains platform-specific configurations.

**Supported Properties:**

* `container`  *string*\
  A **Docker container image reference**. Refer to the official [Docker documentation](https://docs.docker.com/reference/cli/docker/image/ls/) to choose the right base image for your app.\
  Examples:
  * "python:3.8-alpine"
  * "tensorflow/tensorflow:latest-gpu"
  * "blender/blender:latest"<br>
* `private_image`  *boolean*\
  Set this to true if your **image repository is private**.<br>
* `username` *string*\
  Your **Docker Hub username** (only needed if `private_image` is true).<br>
* `token` *string*\
  Your [**Docker Hub Personal Access Token (PAT)**](https://www.docker.com/blog/docker-hub-new-personal-access-tokens/) for authenticating image pull requests (only required if `private_image` is true).<br>
* &#x20;          `secrets`  *object* \
  Your chosen `secret_id` , generated when [Setting up Your Secrets](/launch-with-bytenite/data-sources#setting-up-secrets) to your respective data source provider (e.g., AWS, Google Cloud Storage).&#x20;

**Example:**

```json
{
    "container": "huggingface/transformers-pytorch-cpu:latest",
    "private_image": true,
    "username": "alex_rivers6241",
    "token":"dckr_pat_HgNOmERVLDm1YBSvAJELJeGOOAM",
    "secrets": ["MY_S3_KEY"]
}
```

</details>

In summary, these are the suggested steps to pair your ByteNite app with a Docker container image:

1\. **Build or choose** a Docker image with all the necessary libraries and dependencies.

2\. **Develop your app**’s logic *outside* the image—place your code in the app/ directory.

3\. **Upload your app**  using the ByteNite CLI, referencing your Docker image in the manifest file.

#### Hardware Requirements

At ByteNite, we handle the infrastructure so you can focus on building your apps—not worrying about hardware.

To ensure smooth performance, you’ll define your app’s **minimum hardware requirements**, like the number of CPU cores and memory size. This helps ByteNite allocate machines that meet (or exceed) these requirements, making sure your app runs reliably.

You set these requirements in the `deviceRequirements` field of your manifest.json.

## The commonDeviceRequirements object

```json
{"openapi":"3.1.1","info":{"title":"ByteNite developers API","version":"0.1"},"components":{"schemas":{"commonDeviceRequirements":{"type":"object","properties":{"minCpu":{"type":"number","format":"float","description":"Minimum number of vCPUs required to run the app/engine."},"minMemory":{"type":"number","format":"float","description":"Minimum amount of RAM (GB) required to run the app."},"gpu":{"type":"array","items":{"type":"string"},"description":"Array of GPU models requested to run the app/engine, in order of preference. Use the official GPU identifiers provided by the /wallet/rates endpoint. Leave blank if no GPU is required."}},"description":"DeviceRequirements represents the minimum hardware requirements for running the app/engine."}}}}
```

***

## 👨🏽‍💻 Develop the main script

The entry point script powers your app’s core functionality—it reads input chunks, processes data, and returns results.

What your script can do is nearly limitless. You can run model inferences, process large datasets, render video frames, generate PDFs in bulk, or scrape the web. If it can run inside a container, it can run on ByteNite.

See: [How it Works](/getting-started/how-it-works#examples-of-core-processing-use-cases) for common serverless job examples.

If needed, extend your entry point script by adding custom scripts or libraries to the app/ folder. These can be imported into your main script to support your logic.&#x20;

The key requirement is **how you handle inputs, parameters, and outputs**. These must follow ByteNite’s conventions to ensure your workflow runs smoothly across distributed infrastructure.

**How ByteNite Executes Your Script**

* ByteNite **pulls the container image** specified in your manifest.
* It **overrides the container’s original entry point** and runs the **ByteNite entry point script** instead—your script inside the app/ folder.

This script must align with the programming language and libraries supported by your container image.

{% hint style="info" %}
Make sure any external dependencies your code needs are installed in the container image. This ensures they’re available at runtime.
{% endhint %}

{% hint style="warning" %}
Important: Container Entrypoint ≠ ByteNite Entrypoint

When your app runs:

* ByteNite launches the container based on your specified image.
* Your container’s original entrypoint is overridden.
* ByteNite runs its own entrypoint to execute the script inside the app/ folder.

This setup ensures your runtime environment stays flexible and modular—making it easier to iterate on your app’s logic without changing the container itself.
{% endhint %}

### Default environment variables

Alongside your entry point script, ByteNite injects your container with **environment variables**. These variables provide paths to your app’s input and output folders, cache directories for data sharing and persistence, as well as job parameters and secrets for secure configuration.

Configuring your app’s data flow using these variables ensures your job runs smoothly and interacts properly with ByteNite’s components.

Here are the six preset ByteNite App environment variables:

<details>

<summary><code>TASK_DIR</code>  <em>environment variable</em></summary>

**Description:**

Contains the path to the directory holding a single input data chunk. The chunk is stored in a file named `data.bin`.

* This file holds the raw binary input data for your task, passed by the Partitioning Engine.
* If you use a passthrough partitioner, data.bin is the original data source.

The directory is **automatically created** and contains only this one chunk—you don’t need to manage it manually. Just use this variable to access the input file.

Be sure to **load and decode `data.bin`** based on your app’s expected data type.

If your app doesn’t process input files, you can skip this step.

**Usage (Python):**

```python
task_dir = os.getenv('TASK_DIR')
chunk_path = os.path.join(task_dir, 'data.bin')
```

</details>

<details>

<summary><code>TASK_RESULTS_DIR</code>  <em>environment variable</em></summary>

**Description:**

This is the directory where your app should **store processed results**. Files saved here must be readable by the **Assembling Engine**.

* The assembler collects these files across all runs of your app.
* For passthrough assemblers, any file saved here is directly uploaded to the job’s data destination.

The folder is **automatically created** inside your app's environment. There’s no required output format—just make sure the assembler can access the files.

**Usage (Python):**

```python
task_results_dir = os.getenv('TASK_RESULTS_DIR')
```

</details>

<details>

<summary><code>SHARED_CACHE_DIR</code>  <em>environment variable</em></summary>

**Description:**

Contains the path to a **global, shared, read-only directory** that is accessible to every app, partitioner, and assembler running on ByteNit&#x65;**.** This directory is managed by ByteNite and is intended for **large, immutable resources** that needs to be accessed by your code.

* Use this directory to access resources such as **pre-trained model weights, reference datasets, or common binaries**.
* Any files placed here are available in read-only mode to all running jobs, from any user.

The directory is **automatically mounted** and made available by ByteNite. You do not need to manage its contents or permissions.

**Usage (Python):**

```python
shared_cache_dir = os.getenv('SHARED_CACHE_DIR')
model_path = os.path.join(shared_cache_dir, 'Llama-4-Scout-17B-16E-Instruct-Q4_K_M-00001-of-00002.gguf')
```

</details>

<details>

<summary><code>USER_CACHE_DIR</code>  <em>environment variable</em></summary>

**Description:**

Contains the path to a **user-specific, read/write directory**. This directory is **unique to each user** and is shared across all jobs run by that user.&#x20;

* Use this directory to **store temporary files, intermediate results, or artifacts** that are specific to your user.

The directory is **automatically created** and isolated per user. You do not need to set up or clean up this directory manually.

**Usage (Python):**

```python
user_cache_dir = os.getenv('USER_CACHE_DIR')
file_path = os.path.join(user_cache_dir, 'intermediate_results.npy')
```

</details>

<details>

<summary><code>APP_PARAMS</code>  <em>environment variable</em></summary>

**Description:**

This variable provides your app with **parameters passed through a job**. It contains a dictionary based on the data provided in the **Create Job** request (under `params` -> `app`).

These parameters let you adjust your app’s behavior per job.

For example, a parameter like "case" could control output string formatting, or a parameter "prompt" might contain a text prompt for a stable diffusion pipeline.

**Usage (Python):**

```python
app_params = json.loads(os.getenv('APP_PARAMS'))
```

</details>

<details>

<summary><code>&#x3C;SECRETS></code>  <em>environment variable</em></summary>

**Description**

This environment variable grants your app access to all your secrets stored on ByteNite needed for execution. All referenced secrets are injected at runtime, making them available when your app starts. For details on secret fields, see [Setting Up Secrets](/launch-with-bytenite/data-sources#setting-up-secrets). You can access secrets programmatically in two ways:

1. **Individual Secret Keys**\
   For specific secrets with a known `secret_id`, each credential is injected as a separate environment variable. For example:

* &#x20;   `{{secret_id}}_ACCESS_KEY`
* `{{secret_id}}_SECRET_KEY`

**Usage (Python):**

```python
access_key = os.environ.get('{{secret_id}}_ACCESS_KEY')
secret_key = os.environ.get('{{secret_id}}_SECRET_KEY')
```

2. **Accessing Custom Type Secrets**

For secrets with a `secretType` of `"other"`, the `secretKey` can be accessed directly using the environment variable `{{secret_id}}`.

**Usage (Python):**

```python
secret_key = os.environ.get('{{secret_id}}')
```

</details>

### Example: Python entry point script

Here’s an example[^2] of a Python-based entry point script (`main.py`) that uses the environment variables we just covered.

```python
# === BYTENITE APP - MAIN SCRIPT ===

# Documentation: https://docs.bytenite.com/create-with-bytenite/building-blocks/apps

# == Imports and Environment Variables ==

try:
    import json
    import os
except ImportError as e:
    raise ImportError(f"Required library is missing: {e}")

# Path to the directory containing a single data chunk, passed by your partitioner.
# Note: This folder is automatically created and contains only one chunk. You don't need to create or manage it.
task_dir = os.getenv('TASK_DIR')
if not task_dir:
    raise ValueError("TASK_DIR environment variable is not set or is invalid.")
chunk_path = os.path.join(task_dir, 'data.bin')

# Path to the folder where your app's task results must be saved. The assembler will access these files across all runs of your app.
# Note: The folder is automatically created and passed to your app. There is no required output format—just ensure your assembler can read the files.
task_results_dir = os.getenv('TASK_RESULTS_DIR')
if not task_results_dir:
    raise ValueError("TASK_RESULTS_DIR environment variable is not set or is invalid.")

# App parameters imported from the job request (located under "params" -> "app").
app_params_raw = os.getenv('APP_PARAMS')
if not app_params_raw:
    raise ValueError("APP_PARAMS environment variable is not set or is empty.")
try:
    app_params = json.loads(app_params_raw)
except json.JSONDecodeError as e:
    raise ValueError(f"APP_PARAMS environment variable contains invalid JSON: {e}")


if __name__ == '__main__':
    print("Python task started")
    result_path = os.path.join(task_results_dir, 'processed_chunk.txt')
    try:
        # --------------
        # 1. Reading Inputs
    
        # Example: Expect a text file to be passed by the partitioner
        with open(chunk_path, 'r', encoding="utf-8") as infile:
            my_string = infile.read()

        # --------------
        # 2. Handling Parameters
        
        # Example: Expect the job parameters to have a key named 'case', and the options to be "upper", "lower", and "title"
        case = app_params['case']

        # --------------
        # 3. Developing the Core Functionality
        
        # Example: Process the string based on the case parameter
        if case == "upper":
            my_string = my_string.upper()
        elif case == "lower":
            my_string = my_string.lower()
        elif case == "title":
            my_string = my_string.title()
        else:
            my_string = my_string
        
        # --------------
        # 4. Saving Outputs

        # Example: Save the string directly into a text file to the default task results directory
        with open(os.path.join(task_results_dir, "hello_world_processed.txt"), 'w', encoding="utf-8") as outfile:
            outfile.write(my_string)

    except Exception as e:
        print("Python exception: ", e)
        raise e

```

***

## ☑️ (Optional) Require Parameter Validation: `schema.json`

If your app receives parameters, validating them ahead of time ensures they follow a defined structure. This helps prevent issues like missing keys or malformed data.

You can define a JSON Schema in the `schema.json` file inside your app directory.

Any input parameters submitted to the Jobs API will be checked against this schema before the job starts.

**Example Schema**

Here’s an example of a schema that requires a single input string (prompt) with a maximum length of 50 characters:

{% code title="schema.json" %}

```json
{
  "$id": "db://image-generation-simple-inputs",
  "definitions": {
    "input": {
      "type": "string",
      "description": "A prompt for image generation",
      "maxLength": 50
    }
  },
  "properties": {
    "prompt": {
      "$ref": "#/definitions/input"
    }
  },
  "required": ["prompt"],
  "title": "Stable Diffusion App Schema"
}
```

{% endcode %}

**Why Use a Schema?**

* **Prevents errors**:

  Ensures parameters meet your expected format before the job runs.
* **Generates UI**:

  The schema automatically creates a graphical interface in your Job Launch console, making it easy for you (or your users) to configure and launch jobs from the UI.

***

## 💡 App Development Tips

To get the most out of your ByteNite apps, keep the following principles in mind:

* Your app code is executed by **distributed task runners**. Each task runs independently on a worker machine, based on how your data is partitioned. \
  → **Only include the logic that should run on a single worker**—ByteNite handles all task distribution and resource orchestration for you.
* Within each worker, your app can take advantage of **multi-core architectures**. You’re free to parallelize work across available CPU cores using threads or multiprocessing.
* Avoid implementing custom distributed systems logic. ByteNite’s platform is designed to manage scaling, scheduling, and fault tolerance for you.
* Ensure your **data sources are properly configured** via the Customer API (see [Data Sources](/launch-with-bytenite/data-sources)). Custom data ingestion or export logic within your app can lead to errors, inefficient performance, or increased container runtime—and ultimately, higher costs.
* Incorporate **robust error handling and logging**. This is essential for monitoring, debugging, and improving the reliability of your app in production.

**In summary:**

✅ **Do’s**

* Define the core functionality of your app.
* Use multiple CPU cores to process subtasks in parallel within a single worker.

❌ **Don’ts**

* Distribute tasks to other workers or machines.\
  → Your app already runs within ByteNite’s distributed environment.
* Read from or write to additional data sources directly.\
  → Input/output is managed by ByteNite’s Partitioning and Assembling Engines.

**⚠️ Use with Caution**

* Interact with external services or APIs only when necessary, and only if the required functionality cannot be handled by ByteNite’s Data Engines or built-in integrations.

[^1]: The schema.json is no longer auto-generated with bytenite app new command

[^2]: Not sure how to properly go about updating the example


# Job Templates

A **Job Template** (or simply *Template*) combines Building Blocks into one configuration file for your jobs. It:

* Provides instructions to the services that execute your job.
* Ensures your app and data engines are connected correctly.

By default, ByteNite generates a job template when you start building a new app. This allows you to focus on developing your app without needing to configure the other components upfront.

However, since your app may expect specific data types or formats, you can create and customize a job template to link your app to the appropriate partitioning and assembling engines.

### Job Template file

Example:

{% code title="template.json" %}

```json
{
  "id": "img-gen-diffusers-template",
  "description": "A template for my img-gen-diffusers app",
  "app": "img-gen-diffusers@1",
  "partitioner": "replicate-fanout",
  "assembler": "zipper",
}
```

{% endcode %}

#### **How to create a job template**

You can either:

1. Define the fields manually as shown in the example, or
2. Generate a blank template using the ByteNite CLI:

```
bytenite template new [template_name]
```

#### Key notes

* When you create a new app, a [template is generated automatically ](/create-with-bytenite/building-blocks/apps#app-directory-overview)and is uploaded with the app.
* If you prefer to manage templates separately, you can move your template out of the app folder and use the CLI to manage it independently.

Your template includes a user-defined `id` and an optional `description`. Use the `app`, `partitioner`, and `assembler` fields to specify which components should be used in jobs built from this template:

<details>

<summary><code>app</code>  <em>string</em></summary>

**Description:**

An **app tag** to be used with this template.&#x20;

**Supported Format:**

Please refer to the [Glossary](/other/glossary#tag) definition.

**Examples:**

* `"img-gen-diffusers"`
* `"img-gen-diffusers@1"`
* `"img-gen-diffusers@1.2"`

</details>

<details>

<summary><code>partitioner</code>  <em>string</em></summary>

**Description:**

An **engine tag** to be used with this template.&#x20;

**Supported Format:**

Please refer to the [Glossary](/other/glossary#tag) definition.

**Examples:**

* `"replicate-fanout"`
* `"replicate-fanout@2"`
* `"replicate-fanout@0.4"`

</details>

<details>

<summary><code>assembler</code>  <em>string</em></summary>

**Description:**

An **engine tag** to be used with this template.&#x20;

**Supported Format:**

Please refer to the [Glossary](/other/glossary#tag) definition.

**Examples:**

* `"zipper"`
* `"zipper@3"`
* `"zipper@1.0"`

</details>


# Containers & Environments

Alongside your entry point script, ByteNite injects your container with **environment variables**. These variables provide paths to your app’s input and output folders, cache directories for data sharing and persistence, as well as job parameters and secrets for secure configuration.

Configuring your app’s data flow using these variables ensures your job runs smoothly and interacts properly with ByteNite’s components.

This page explains how ByteNite’s environment works for your containers, focusing on two key areas:

* **Secret management**: How secrets are made available to your app (data source/destination linking, environment variable injection, and API-based access).
* **Cache directories**: How ByteNite provides built-in directories for storing and accessing data at runtime.<br>

You’ll learn how to structure your `platformConfig` object within your `manifest.json`, what environment variables are available inside your container, and how these features impact your build and deployment process.

***

## 🔑 Secret Management Approaches

ByteNite supports multiple ways to provide secrets to your app, depending on your workflow:

#### 🔗 Job Data Source/Destination Linking

**How it works:**

* You link secrets to data sources/destinations (e.g., S3, GCS) during job submission (via UI or [API](/launch-with-bytenite/jobs#submit-a-data-source-and-destination)).
* The `platformConfig`'s `secrets` property is typically **not required** for this approach.
* The secret is referenced in the job’s [data source/destination config](/launch-with-bytenite/data-sources#setting-up-data-sources), not in the platform config.

**Example (`platformConfig`):**

```json
{
  "container": "python:3.8-alpine",
  "private_image": false
}
```

> *No need to reference secrets in* `platformConfig` *for data movement.*

#### **Build/Deployment:**

* Build your container as usual.
* ByteNite manages authentication and data transfer using the linked secrets, **so your code never handles credentials**.

#### **When to use:**

* When your job only needs to read or write data (like to S3 or GCS) and does not need to make custom API calls.
* This method is simple and secure, as **your code never sees the credentials** and ByteNite manages all authentication and data transfer automatically.

#### ✍️ Environment Variable Injection

**How it works:**

* Use this when your app code needs to interact with external services (APIs, SDKs, databases) that require credentials at runtime.
* ByteNite injects your secrets as environment variables so your code can securely access them.

**Typical use cases:**

* Authenticating to external APIs (e.g., AWS, GCP, OpenRouter, Twilio, Hugging Face, etc.)
* Connecting to managed databases or message queues
* Using SDKs or CLI tools that expect credentials in environment variables

**Example (`platformConfig`):**

```json
{
  "container": "python:3.8-alpine",
  "private_image": false,
  "secrets": ["MY_SECRET_ID"]
}
```

Once your `manifest.json` is configured, you can access the injected secrets in your code like shown below:

**Example (Python):**

```python
# Retrieve the access & secret key for your secret
access_key = os.environ.get('MY_SECRET_ID_ACCESS_KEY')
secret_key = os.environ.get('MY_SECRET_ID_SECRET_KEY')
```

**Build/Deployment:**

* Build your container as usual.
* Ensure your code reads secrets from environment variables.
* Ensure the correct secret IDs are referenced in `platformConfig`.

#### **When to use:**

* When your code needs to make authenticated requests to external services, use cloud SDKs, or perform any operation that requires direct access to credentials at runtime.

***

## 📂 ByteNite Cache Directory Environment Variables

In addition to secrets, ByteNite automatically injects cache directory environment variables (`USER_CACHE_DIR` and `SHARED_CACHE_DIR`) into your container at runtime. These directories are essential for storing user-specific data and accessing shared resources within your app environment.

For a full explanation of how these variables work, including usage examples and best practices, see the [Environment Variables](/create-with-bytenite/building-blocks/apps#default-environment-variables) section.

***

#### **Summary:**

* **Secrets**: Use data source/destination linking for simple data movement, or environment variable injection for direct credential access in your code.
* **Cache Directories**: Use `USER_CACHE_DIR` for user-specific, persistent storage; use `SHARED_CACHE_DIR` for global, read-only resources.
* All these environment variables are automatically injected by ByteNite and available inside your container at runtime.

By understanding these environment variables and secret management approaches, you can configure your containers securely and efficiently, and make the most of the ByteNite platform.


# Developer CLI

The Dev CLI is a tool for developers to create and manage apps on ByteNite.

## Download & Install

### Linux

Follow these steps to install the ByteNite CLI on Ubuntu, Debian, or similar distributions.

1. **Add the ByteNite Repository**

```bash
echo "deb [trusted=yes] https://storage.googleapis.com/bytenite-prod-apt-repo/debs ./" | sudo tee /etc/apt/sources.list.d/bytenite.list
```

2. **Update Package Lists**

```bash
sudo apt update
```

3. **Install the ByteNite CLI**

```bash
sudo apt install bytenite
```

#### Troubleshooting

If you encounter any issues during installation:

* Make sure your system is up-to-date:

  ```bash
  sudo apt update && sudo apt upgrade
  ```
* Verify the repository was correctly added:

  ```bash
  cat /etc/apt/sources.list.d/bytenite.list
  ```
* Check if the package is available:

  ```bash
  apt search bytenite
  ```

### Mac

#### Installation

1. **Add the Bytenite Tap**

```bash
brew tap ByteNite2/bytenite-dev-cli https://github.com/ByteNite2/bytenite-dev-cli.git
```

2. **Install the CLI**

```bash
brew install bytenite
```

<details>

<summary>Additional Permissions for Mac Users</summary>

Mac users might need to manually grant permissions in **System Settings > Privacy & Security** after executing a ByteNite command for the first time.

Follow the necessary steps as shown in the image below to let your OS know ByteNite is safe to use.

<img src="https://1271894904-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC4oKwqyUo55Lw35MjazY%2Fuploads%2FzXqdAX7pEnA3RfqHkGKP%2Fmac-privacy-security-1.png?alt=media&amp;token=b420f8fb-125c-480a-ab13-ad55994c9520" alt="MacOS System Settings, Privacy &#x26; Security, &#x22;bytenite&#x22; was blocked to protect your Mac, Allow Anyway" data-size="original">   &#x20;

</details>

#### Updating

1. **Update Homebrew's formula list (including your tap)**

```bash
brew update
```

2. **Upgrade the bytenite package specifically**

```bash
brew upgrade bytenite
```

### Windows

Download and run the latest Windows release from [ByteNite CLI on GitHub](https://github.com/ByteNite2/bytenite-dev-cli/releases).

***

## **Verify Installation**

Check that the installation was successful by using:

```bash
bytenite version
```

***

## Authenticate

To authenticate, run:

```bash
bytenite auth
```

This will open an oAuth2 authentication page in your browser. The login is automatic if you're already logged in on ByteNite.

After successful authentication, credentials will be stored in the application support or configuration directory:

* **Linux**: `/$HOME/.config/bytenite-cli/auth-prod.json`
* **Mac**: `/Users/[user]/Library/Application Support/bytenite-cli/auth-prod.json`

***

## Commands & Usage

Run the help command to get started with the ByteNite Dev CLI:

```bash
bytenite --help
```

**Authentication**

* Authenticate with OAuth2: `bytenite auth`

**Version**

* Get Dev CLI Version: `bytenite version`

**App Commands**

* App Command Info: `bytenite app --help`
* Initialize New App: `bytenite app new [app_name]`
* Push/Upload App: `bytenite app push [app_folder]`
* Pull/Download App: `bytenite app pull [app_tag]`
* Get App Details: `bytenite app get [app_tag]`
* List Existing Apps: `bytenite app list`
* Activate App: `bytenite app activate [app_tag]`
* Deactivate App: `bytenite app deactivate [app_tag]`
* Get App Status: `bytenite app status [app_tag]`

**Template Commands**

* Template Command Info: `bytenite template --help`
* Initialize New Template: `bytenite template new [template_id]`
* Push/Upload Template: `bytenite template push [template_filepath]`
* Pull/Download Template: `bytenite template pull [template_id]`
* Get Template Details: `bytenite template get [template_id]`
* List Existing Templates: `bytenite template list`

**Engine Commands**

* Engine Command Help: `bytenite engine --help`
* Initialize New Engine: `bytenite engine new [engine_name]`
* Push/Upload Engine: `bytenite engine push [engine_folder]`&#x20;
* Pull/Download Engine: `bytenite engine pull [engine_tag]`
* Get Engine Details: `bytenite engine get [engine_tag]`
* List Existing Engines: `bytenite engine list`&#x20;


# Data Sources

Data storage methods supported by ByteNite

If your app needs data to function (which most do), it’s crucial to **configure your data connections** properly. This guide walks you through securely storing credentials, testing connections, and setting up your data sources.

ByteNite jobs can **read and write from popular storage services**, including Amazon S3 and Google Cloud Storage buckets.

#### How it works

* **Secrets** handle external credentials securely.
* **Data Sources** connect your storage options to your ByteNite jobs.

Once configured, secrets and data sources work seamlessly across any job.

***

## 🔐 Setting up secrets

If you’re using an authenticated service like S3, you’ll store your credentials securely in your ByteNite account—**keeping them out of your code**.

#### Steps:

1. **Use the `secretType` field** to select your secret provider (e.g., AWS, Google Cloud Storage).

   ByteNite supports multiple providers. See: [#supported-data-source-options](#supported-data-source-options "mention").
2. **Send a request to the** [Secrets](/api-reference/authentication-api/secrets) **endpoint** to securely create and store your secret in your account.

   This unlocks access to your data sources without hardcoding credentials.

Configure your secret request with the following parameters:

<details>

<summary><code>id</code>  <em><strong>string</strong></em></summary>

**Description:**

A given ID for your secret. \
***Hint:*** Use a string that can easily help remember the credential's scope, permissions, and provider.

**Example:**

"aws\_full\_s3\_access\_key"

</details>

<details>

<summary><code>name</code>  <em><strong>string</strong></em></summary>

**Description:**

A descriptive name for your secret.

**Example:**

"John's AWS S3 Full Access Key"

</details>

<details>

<summary><code>secretType</code>  <em><strong>string</strong></em></summary>

**Description:**

The data source provider of this secret.

**Supported Values:**

Please see [#supported-data-source-options](#supported-data-source-options "mention")

**Example:**

"s3"

</details>

<details>

<summary><code>accessKey</code>  <em><strong>string</strong></em></summary>

**Description:**

Your data source's access key.

**Example:**

"AKIAIOSFODNN7EXAMPLE"

</details>

<details>

<summary><code>secretKey</code>  <em><strong>string</strong></em></summary>

**Description:**

Your data source's secret key.

**Example:**

"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"

</details>

<details>

<summary><code>expiresAt</code>  <em><strong>string</strong></em></summary>

**Description:**

A given expiry date for your secret, in ISO 8601 format.

**Example:**

"2025-12-29T18:02:27.140Z"

</details>

Here's an example of a secret request body:

{% code title="POST /auth/secrets" %}

```json
{
    "secret": {
        "id": "aws_full_s3_access_key",
        "name": "John's AWS S3 Full Bucket Access",
        "secretType": "s3",
        "accessKey": "AKIAXXEXAMPLEEXAMPLEX",
        "expiresAt": "2025-12-29T18:02:27.140Z"    
    },
    "secretKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
}
```

{% endcode %}

***

## 🔗 Setting up data sources

To enable **input and output** with your current storage provider, configure your data sources. You’ll provide a **`dataSource` object** for both inputs (called Data Source) and outputs (called Data Destination). Once both are set, you can:

* **Test your `dataSource` object** by sending a request to the /datasource/test endpoint.
* **Attach a Data Source** to a job via the `dataSource` field in the /jobs endpoint.
* **Attach a Data Destination** to a job via the `dataDestination` field in the /jobs endpoint.

**About the dataSource Object**

The fields below define the dataSource object. Please note:

* The `params` object varies depending on the data source type.
* For data sources requiring authentication (like S3), provide the secret ID for the required credentials in the params body.
* Use the `bypass` data source descriptor if your app doesn’t require input or output (e.g., no input data or output files).

<details>

<summary><code>dataSourceDescriptor</code>  <em><strong>string</strong></em></summary>

**Description:**

The data source type selector.

**Supported Values:**

Please see [#supported-data-source-options](#supported-data-source-options "mention")for all data source configuration parameters.&#x20;

Use `bypass` to skip a data source.

**Example:**

"s3"

</details>

<details>

<summary><code>params</code>  <em><strong>object</strong></em></summary>

**Description:**

The data source parameters.

**Supported Properties:**

* `@type` \
  A params object type. Please see [#supported-data-source-options](#supported-data-source-options "mention").
* Other parameters. Please refer to the specific guides under [#supported-data-source-options](#supported-data-source-options "mention").

**Example:**

```json
{  
    "@type": "type.googleapis.com/bytenite.data_source.S3DataSource",  
    "name": "/vids/big_buck_bunny.mp4",
    "bucketName": "my-app-data-bucket-12345",
    "cloudRegion": "us-east-2",
    "secret_id": "aws_full_s3_access_key"
}
```

</details>

Here is a full `dataSource`  object example:

{% code title="POST /customer/jobs/datasource/info" %}

```json
{
    "dataSource": {  
        "dataSourceDescriptor": "s3", 
        "params": {  
            "@type": "type.googleapis.com/bytenite.data_source.S3DataSource",  
            "name": "/vids/big_buck_bunny.mp4",
            "bucketName": "my-app-data-bucket-12345",
            "cloudRegion": "us-east-2",
            "secret_id": "aws_full_s3_access_key"
        }  
    }
}
```

{% endcode %}

***

## ☁️ Supported data source options

Below is a list of currently supported data source connections and parameters for both inputs and outputs.

### I/O data sources

<table data-view="cards"><thead><tr><th></th><th></th><th></th><th></th><th data-hidden data-card-cover data-type="files"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><h3>AWS S3</h3></td><td>secretType : <code>aws</code></td><td>dataSourceDescriptor : <code>aws</code></td><td>@type : <code>type.googleapis.com/bytenite.data_source.S3DataSource</code></td><td><a href="https://1271894904-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC4oKwqyUo55Lw35MjazY%2Fuploads%2FwAxpOVilXFrrQLBfMZ7w%2Faws-data-source-cover.webp?alt=media&amp;token=c6e96b31-5393-4ff0-a6c8-7499d686f033">aws-data-source-cover.webp</a></td><td><a href="/launch-with-bytenite/data-sources/aws-s3">AWS S3</a></td></tr><tr><td><h3>Google Cloud Storage</h3></td><td>secretType : <code>gcp</code></td><td>dataSourceDescriptor : <code>gcp</code></td><td>@type : <code>type.googleapis.com/bytenite.data_source.S3DataSource</code></td><td><a href="https://1271894904-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC4oKwqyUo55Lw35MjazY%2Fuploads%2FrJ7qYz7RzA2zPGn9i6xO%2Fgcp-data-source-cover.webp?alt=media&amp;token=938e84bc-2404-4eaf-a0f7-95d744cd580f">gcp-data-source-cover.webp</a></td><td><a href="/launch-with-bytenite/data-sources/google-cloud-storage">Google Cloud Storage</a></td></tr><tr><td><h3>Storj</h3></td><td>secretType : <code>storj</code></td><td>dataSourceDescriptor : <code>storj</code></td><td>@type : <code>type.googleapis.com/bytenite.data_source.S3DataSource</code></td><td><a href="https://1271894904-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC4oKwqyUo55Lw35MjazY%2Fuploads%2F9o9ZbDMTo1Oa5JQISu3P%2Fstorj-data-sources-cover.webp?alt=media&amp;token=cd5c532f-37b3-4c7e-83c1-7c1239c39dd3">storj-data-sources-cover.webp</a></td><td><a href="/launch-with-bytenite/data-sources/storj">Storj</a></td></tr></tbody></table>

### Input-only data sources

<table data-view="cards"><thead><tr><th></th><th></th><th></th><th></th><th data-hidden data-card-cover data-type="files"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><h3>Generic HTTP</h3></td><td></td><td>dataSourceDescriptor : <code>url</code></td><td>@type: <code>type.googleapis.com/bytenite.data_source.HttpDataSource</code></td><td><a href="https://1271894904-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC4oKwqyUo55Lw35MjazY%2Fuploads%2F3ay21a7rJ03fjZAeoNck%2Fhttp-data-source-cover.webp?alt=media&amp;token=81636a37-5f33-40f4-bad1-3c98ddd0a565">http-data-source-cover.webp</a></td><td><a href="/launch-with-bytenite/data-sources/http">HTTP</a></td></tr><tr><td><h3>File Upload</h3></td><td></td><td>dataSourceDescriptor : <code>file</code></td><td>@type: <code>type.googleapis.com/bytenite.data_source.LocalFileDataSource</code></td><td><a href="https://1271894904-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC4oKwqyUo55Lw35MjazY%2Fuploads%2FHFCywIR1svwTUXIgQAzX%2Ffile-upload-data-source-cover.webp?alt=media&amp;token=a52cc0be-ae25-470f-a93a-169aa6a53c1b">file-upload-data-source-cover.webp</a></td><td><a href="/launch-with-bytenite/data-sources/file-upload">File Upload</a></td></tr></tbody></table>

### Output-only data sources

<table data-view="cards"><thead><tr><th></th><th></th><th></th><th></th><th data-hidden data-card-cover data-type="files"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><h3>Temporary Bucket</h3></td><td></td><td>dataSourceDescriptor : <code>bucket</code></td><td></td><td><a href="https://1271894904-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC4oKwqyUo55Lw35MjazY%2Fuploads%2F4fKJ0u5ivGPRIpswSFpr%2Ftemporary-bucket-data-source-cover.webp?alt=media&amp;token=cb144e37-8a62-4af7-af56-0bdad96e5fbf">temporary-bucket-data-source-cover.webp</a></td><td><a href="/launch-with-bytenite/data-sources/temporary-bucket">Temporary Bucket</a></td></tr></tbody></table>


# AWS S3

## Introduction

Amazon S3 (Simple Storage Service) is a scalable, high-speed, web-based cloud storage service designed for online backup and archiving of data and applications. It offers secure, durable, and highly-scalable object storage, making it ideal for a wide range of use cases, from data lakes and mobile applications to backup and restore operations.

Follow the guide below to set up an account and get IAM credentials on AWS S3:

<details>

<summary>Getting Started with  <img src="https://1271894904-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC4oKwqyUo55Lw35MjazY%2Fuploads%2FuafL1BbdXriTsqdc4trW%2Faws-logo.png?alt=media&amp;token=738d2d8c-8c2d-4c0e-b25d-0607adaab802" alt="AWS" data-size="line">  S3</summary>

## Getting Started with AWS S3&#x20;

#### 1. **Create an AWS Account**:&#x20;

Visit [aws.amazon.com](https://aws.amazon.com/), click “**Create an AWS Account**”, and follow the steps to register. Provide payment information and verify your identity to activate the account.&#x20;

#### 2. **Access S3**:&#x20;

Log in to the AWS Console, search for **S3**, and navigate to the S3 dashboard.&#x20;

#### 3. **Create a Bucket**:&#x20;

* Click “**Create Bucket**” in the S3 dashboard.&#x20;
* Provide a unique bucket name and choose a region (e.g., `us-east-1`).&#x20;
* Keep public access blocked unless specific use cases require otherwise.
* Finalize the setup by clicking “**Create Bucket**”.

***

## Setting Up IAM User for S3 Access&#x20;

#### 1. **Open IAM Service**:&#x20;

In the AWS Console, search for **IAM** and go to **Users**.&#x20;

#### 2. Create a User:&#x20;

* Click “**Add Users**”, provide a username (e.g., `s3-bytenite-user`), and enable **Programmatic Access**.
* Attach the `AmazonS3FullAccess` policy or create a custom policy for specific bucket access.

#### &#x20;3. Generate Credentials:&#x20;

* Complete the user creation process and download the **Access Key ID** and **Secret Access Key**.&#x20;
* Save these credentials securely; they will not be displayed again.

</details>

***

## S3 Secret

{% hint style="info" %}
`secretType`  : **`s3`**
{% endhint %}

If your S3 bucket requires authentication for read or write access, set up a secret to store your S3 credentials securely with ByteNite (see [Data Sources](/launch-with-bytenite/data-sources#setting-up-secrets))

Here's an example of a request body of the [Secrets](/api-reference/authentication-api/secrets) endpoint for saving S3 keys:

{% code title="POST /auth/secrets" %}

```json
{
    "secret": {
        "id": "my_aws_secret",
        "secretType": "s3",
        "expiresAt": "2025-12-29T18:02:27.140Z", 
        "accessKey": "AKIAXXEXAMPLEEXAMPLEX",
        "name": "My AWS Full Bucket Access"
    },
    "secretKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
}
```

{% endcode %}

***

## S3 Data Source Object

{% hint style="info" %}
`dataSourceDescriptor`  : **`s3`**

`@type`  : [**`type.googleapis.com/bytenite.data_source.S3DataSource`**](#user-content-fn-1)[^1]&#x20;
{% endhint %}

Set up your data source with S3 using the your previously configured S3 secret and the following `params` :

<details>

<summary><code>@type</code>  <em><strong>string</strong></em></summary>

**Description:**

Use the `type.googleapis.com/bytenite.data_source.S3DataSource` params type.

</details>

<details>

<summary><code>bucketName</code>  <em><strong>string</strong></em></summary>

**Description:**

The name of your S3 bucket.

**Example:**

"my-app-data-bucket-12345"

</details>

<details>

<summary><code>cloudRegion</code>  <em><strong>string</strong></em></summary>

**Description:**

The S3 bucket's region name.

**Example:**

"us-east-2"

</details>

<details>

<summary><code>name</code>  <em><strong>string</strong></em></summary>

**Description:**

* *Usage for **Data Sources:***\
  The **path** to your input **file** following the bucket name.
* *Usage for **Data Destinations:***\
  The **path** to the output **folder** following the bucket name. Note: a path will be created if it doesn't exist.

**Example:**

* *Data Source:*\
  "/vids/big\_buck\_bunny.mp4"
* *Data Destination:*\
  "/vids/encoded/"

</details>

<details>

<summary><code>secret_id</code>  <em><strong>string</strong></em></summary>

**Description:**

The ID of an existing `s3` secret.

**Example:**

"my\_aws\_secret"

</details>

Here is an example S3 data source and destination request body:

{% code title="POST /customer/jobs/{jobId}/datasource" %}

```json
{
    "dataSource": {  
        "dataSourceDescriptor": "s3", 
        "params": {  
            "@type": "type.googleapis.com/bytenite.data_source.S3DataSource",  
            "name": "/vids/big_buck_bunny.mp4",
            "bucketName": "my-app-data-bucket-12345",
            "cloudRegion": "us-east-2",
            "secret_id": "my_aws_secret"
        }  
    },
    
    "dataDestination": {  
        "dataSourceDescriptor": "s3", 
        "params": {  
            "@type": "type.googleapis.com/bytenite.data_source.S3DataSource",  
            "name": "/vids/encoded/",
            "bucketName": "my-app-data-bucket-12345",
            "cloudRegion": "us-east-2",
            "secret_id": "my_aws_secret"
        }  
    }
}
```

{% endcode %}

[^1]: This data source belongs to the S3-compatible object storage category. We use the same API request structure for all data sources having this @type.


# Google Cloud Storage

## Introduction

Google Cloud Storage offers a highly scalable, secure, and durable object storage service designed to handle unstructured data across various use cases. With a unified API and integration across Google Cloud services, it supports efficient data retrieval and storage management. Its tiered storage options—ranging from high-performance to cost-effective archival—make it a versatile solution. Beyond its native ecosystem, Google Cloud Storage is widely adopted for hybrid and multi-cloud strategies due to its interoperability and global availability.

Follow the guide below to set up an account and get HMAC credentials on GCP:

<details>

<summary>Getting Started with  <img src="https://1271894904-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC4oKwqyUo55Lw35MjazY%2Fuploads%2FIeOeklbUgjQIqpwZKvu0%2Fgoogle-cloud-logo-full.png?alt=media&amp;token=46fd0001-8c36-4c79-b65b-521d3cd55a0e" alt="" data-size="line"> Storage</summary>

## Setting Up Google Cloud Storage

**1. Create a Google Cloud Account:**

* Visit the [Google Cloud website](https://cloud.google.com/) and click on “**Get started for free**.”
* Follow the prompts to set up your account, including verifying your email and providing billing information.

**2. Access the Google Cloud Console:**

* Once your account is active, log in to the [Google Cloud Console](https://console.cloud.google.com/).

**3. Create a Storage Bucket:**

* In the console, navigate to the Cloud Storage section.
* Click on “**Create bucket.**”
* Provide a globally unique name for your bucket.
* Select a location for your bucket (e.g., “US”).
* Choose a default storage class (e.g., “Standard”).
* Set access control to “Uniform” to manage permissions uniformly at the bucket level.
* Click “**Create**” to finalize the bucket setup.

***

## Generating Google Cloud Storage Credentials

To allow ByteNite to interact securely with your Google Cloud Storage buckets, you need to create a service account and generate HMAC (Hash-based Message Authentication Code) credentials.

**1. Create a Service Account:**

* In the Google Cloud Console, navigate to **IAM & Admin** > **Service Accounts**.
* Click on “**Create Service Account**.”
* Provide a name (e.g., bytenite-service-account) and an optional description.
* Click “**Create and Continue.**”

**2. Assign Permissions to the Service Account:**

* Assign the Storage Object Admin role to grant full control over objects in your buckets.
* Click “**Continue**,” then “**Done**” to finish creating the service account.

**3. Generate HMAC Credentials:**

* In the Google Cloud Console, navigate to **Cloud Storage** > **Settings**.
* Open the **Interoperability** tab.
* Under Service Account HMAC, click “**Create a key for a service account**.”
* Select the service account you created earlier (bytenite-service-account).
* Click “**Create Key**.”
* The console will display the **Access Key** and **Secret Key**.
* Important: Save these credentials securely, as the Secret Key will not be displayed again.

**Additional Notes:**

* For comprehensive details about creating buckets, refer to the official Google Cloud documentation on [creating buckets](https://cloud.google.com/storage/docs/creating-buckets).
* For detailed information on managing HMAC keys, consult the documentation on [HMAC keys](https://cloud.google.com/storage/docs/authentication/hmackeys).

</details>

***

## Google Cloud Storage Secret&#x20;

{% hint style="info" %}
`secretType`  : **`gcp`**
{% endhint %}

If your Google Cloud bucket requires authentication for read or write access, set up a secret to store your Service Account HMAC credentials securely with ByteNite (see [Data Sources](/launch-with-bytenite/data-sources#setting-up-secrets))

Here's an example of a request body of the [Secrets](/api-reference/authentication-api/secrets) endpoint for saving Google Cloud keys:

{% code title="POST /auth/secrets" %}

```json
{
    "secret": {
        "id": "my_gcp_secret",
        "secretType": "gcp",
        "expiresAt": "2025-12-29T18:02:27.140Z", 
        "accessKey": "GOOG1AB7QD3TY4NSFIZHD4KPB6LVB4F53UJGEZEMRJDXO5PUYDXAOSIKUFNI",
        "name": "GCP Bucket Admin Project 'My App'"
    },
    "secretKey": "aBcDeFgHiJkLmNoPqRsTuVwXyZ1234567890+/ExAmPlEkEy"
}
```

{% endcode %}

***

## Google Cloud Storage Data Source Object

{% hint style="info" %}
`dataSourceDescriptor`  : **`gcp`**

`@type`  : [**`type.googleapis.com/bytenite.data_source.S3DataSource`**](#user-content-fn-1)[^1]&#x20;
{% endhint %}

Set up your data source with Google Cloud storage using the your previously configured gcp secret and the following `params` :

<details>

<summary><code>@type</code>  <em><strong>string</strong></em></summary>

**Description:**

Use the `type.googleapis.com/bytenite.data_source.S3DataSource` params type.

</details>

<details>

<summary><code>bucketName</code>  <em><strong>string</strong></em></summary>

**Description:**

The name of your Google Cloud bucket.

**Example:**

"my-app-data-bucket-12345"

</details>

<details>

<summary><code>cloudRegion</code>  <em><strong>string</strong></em></summary>

**Description:**

The Google Cloud bucket's region name.

**Example:**

"us-west2-b"

</details>

<details>

<summary><code>name</code>  <em><strong>string</strong></em></summary>

**Description:**

* *Usage for **Data Sources**:*\
  The **path** to your input **file** following the bucket name.
* *Usage for **Data Destinations**:*\
  The **path** to the output **folder** following the bucket name. Note: a path will be created if it doesn't exist.

**Example:**

* *Data Source:*\
  "/vids/big\_buck\_bunny.mp4"
* *Data Destination:*\
  "/vids/encoded/"

</details>

<details>

<summary><code>secret_id</code>  <em><strong>string</strong></em></summary>

**Description:**

The ID of an existing `gcp` secret.

**Example:**

"my\_gcp\_secret"

</details>

Here is an example Google Cloud data source and destination request body:

{% code title="POST /customer/jobs/{jobId}/datasource" %}

```json
{
    "dataSource": {  
        "dataSourceDescriptor": "gcp", 
        "params": {  
            "@type": "type.googleapis.com/bytenite.data_source.S3DataSource",  
            "name": "/vids/big_buck_bunny.mp4",
            "bucketName": "my-app-data-bucket-12345",
            "cloudRegion": "us-west2-b",
            "secret_id": "my_gcp_secret"
        }  
    },
    
    "dataDestination": {  
        "dataSourceDescriptor": "gcp", 
        "params": {  
            "@type": "type.googleapis.com/bytenite.data_source.S3DataSource",  
            "name": "/vids/encoded/",
            "bucketName": "my-app-data-bucket-12345",
            "cloudRegion": "us-west2-b",
            "secret_id": "my_gcp_secret"
        }  
    }
}
```

{% endcode %}

[^1]: This data source belongs to the S3-compatible object storage category. We use the same API request structure for all data sources having this @type.


# Storj

## Introduction

Storj is a decentralized cloud storage platform that offers secure, private, and cost-effective data storage. By distributing data across a global network of nodes, Storj ensures highly-available and resilient data access, while securing cost savings to up to 90% than traditional cloud providers.

Follow the guide below to set up an account and get S3-compatible access keys on Storj:

<details>

<summary>Getting Started with  <img src="https://1271894904-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC4oKwqyUo55Lw35MjazY%2Fuploads%2FeMriWMCRv96nIibjjDC0%2Fstorj-logo-full-color.png?alt=media&amp;token=92f34ba5-4bcb-44b4-9116-9874ab853760" alt="Storj" data-size="line"></summary>

## Getting Started with Storj

**1. Create a Storj Account Using ByteNite's Referral Link:**

Visit the link below to create an account on Storj&#x20;

🔗 [<mark style="color:purple;">**Unlock 25 GB Free Storage on Storj - ByteNite's Referral Link**</mark>](https://us1.storj.io/signup?partner=bytenite)

Complete the registration process by verifying your email and setting up your password. You can start with a free trial or select a paid plan based on your needs.

**2. Log in to the Storj Console:**

Access your [Storj console](https://www.storj.io/login) using your account credentials.

**3. Create a Project:**

* Once logged in, click “**New Project**.”
* Provide a project name (e.g., “My S3 Project”).
* Click “**Create Project**” to finalize.

**4. Create a Bucket:**

* Inside your project dashboard, navigate to the “**Buckets**” tab.
* Click “**New Bucket**.”
* Provide a bucket name (e.g., my-s3-bucket).
* Optionally, configure additional settings such as default encryption or access permissions.
* Click “**Create Bucket**” to complete the setup.

***

## Setting Up S3-Compatible Access Keys for Storj

**1. Navigate to API Keys:**

* Inside your project dashboard, click on the “**Access Keys**” tab in the navigation bar.

**2. Generate an Access Grant:**

* Click “**New Access Key**.”
* Select the "**S3 Credentials"** configuration checkbox.
* Choose the scope of the access (e.g., full project access or limited to specific buckets).

**3. Retrieve Your S3-Compatible Credentials:**

* Once the access grant is generated, the console will display the **Access Key** and **Secret Key** for S3 compatibility.
* Save these credentials securely, as the Secret Key will not be shown again.

</details>

***

## Storj Secret&#x20;

{% hint style="info" %}
`secretType`  : **`storj`**
{% endhint %}

If your Storj bucket requires authentication for read or write access, set up a secret to store your S3-compatible credentials securely with ByteNite (see [Data Sources](/launch-with-bytenite/data-sources#setting-up-secrets))

Here's an example of a request body of the [Secrets](/api-reference/authentication-api/secrets) endpoint for saving Storj keys:

{% code title="POST /auth/secrets" %}

```json
{
    "secret": {
        "id": "my_storj_secret",
        "secretType": "storj",
        "expiresAt": "2025-12-29T18:02:27.140Z", 
        "accessKey": "jwcxl2mccgasmhs1dcir5ex4mple",
        "name": "Storj Full Access S3 Keys - Project 'My App'"
    },
    "secretKey": "jzwi4pcamnhyjpldu4my2cmfscmg55slex4mpleex4mpleex4mple"
}
```

{% endcode %}

***

## Storj Data Source Object

{% hint style="info" %}
`dataSourceDescriptor`  : **`storj`**

`@type`  : [**`type.googleapis.com/bytenite.data_source.S3DataSource`**](#user-content-fn-1)[^1]&#x20;
{% endhint %}

Set up your data source with Storj using the your previously configured storj secret and the following `params` :

<details>

<summary><code>@type</code>  <em><strong>string</strong></em></summary>

**Description:**

Use the `type.googleapis.com/bytenite.data_source.S3DataSource` params type.

</details>

<details>

<summary><code>bucketName</code>  <em><strong>string</strong></em></summary>

**Description:**

The name of your Storj bucket.

**Example:**

"my-app-data-bucket-12345"

</details>

<details>

<summary><code>cloudRegion</code>  <em><strong>string</strong></em></summary>

**Description:**

Use `global`  as the Storj bucket region.

</details>

<details>

<summary><code>name</code>  <em><strong>string</strong></em></summary>

**Description:**

* *Usage for **Data Sources**:*\
  The **path** to your input **file** following the bucket name.
* *Usage for **Data Destinations**:*\
  The **path** to the output **folder** following the bucket name. Note: a path will be created if it doesn't exist.

**Example:**

* *Data Source:*\
  "/vids/big\_buck\_bunny.mp4"
* *Data Destination:*\
  "/vids/encoded/"

</details>

<details>

<summary><code>secret_id</code>  <em><strong>string</strong></em></summary>

**Description:**

The ID of an existing `storj` secret.

**Example:**

"my\_storj\_secret"

</details>

Here is an example Storj data source and destination request body:

{% code title="POST /customer/jobs/{jobId}/datasource" %}

```json
{
    "dataSource": {  
        "dataSourceDescriptor": "storj", 
        "params": {  
            "@type": "type.googleapis.com/bytenite.data_source.S3DataSource",  
            "name": "/vids/big_buck_bunny.mp4",
            "bucketName": "my-app-data-bucket-12345",
            "cloudRegion": "global",
            "secret_id": "my_storj_secret"
        }  
    },
    
    "dataDestination": {  
        "dataSourceDescriptor": "storj", 
        "params": {  
            "@type": "type.googleapis.com/bytenite.data_source.S3DataSource",  
            "name": "/vids/encoded/",
            "bucketName": "my-app-data-bucket-12345",
            "cloudRegion": "global",
            "secret_id": "my_storj_secret"
        }  
    }
}
```

{% endcode %}

[^1]: This data source belongs to the S3-compatible object storage category. We use the same API request structure for all data sources having this @type.


# HTTP

## Introduction

You can fetch files directly from a public URL pointing to the raw resource, which is especially useful for utilizing temporary access URLs generated by cloud storage providers not integrated with ByteNite.&#x20;

Keep in mind that an HTTP source serves solely as a data origin, meaning it cannot be used as a data destination. This ensures that data fetched via HTTP can be read and processed, but not directly modified or uploaded back through this method.

## HTTP Data Source Object

{% hint style="info" %}
`dataSourceDescriptor`  : **`url`**

`@type` : **`type.googleapis.com/bytenite.data_source.HttpDataSource`**
{% endhint %}

To configure your HTTP data source, specify a valid URL pointing to the raw resource in your dataSource object, as in the following example:

{% code title="POST /customer/jobs/{jobId}/datasource" %}

```json
{
  "dataSource": {
    "dataSourceDescriptor": "url",
    "params": {
      "@type": "type.googleapis.com/bytenite.data_source.HttpDataSource", 
      "url": "https://storage.googleapis.com/video-test-public/input/bbb.mp4"
    }
  }
}
```

{% endcode %}


# File Upload

Uploading input files directly from your computer makes it convenient to process local content for tests.

We require a 4-step process for uploading local files, which involves configuring a data source, retrieving a temporary upload URL, uploading the file, and notifying the server upon completion.

{% stepper %}
{% step %}

### Set Local File Data Source Object

{% hint style="info" %}
`dataSourceDescriptor`: **`file`**

`@type`:**`type.googleapis.com/bytenite.data_source.LocalFileDataSource`**
{% endhint %}

When setting up a data source, use the following `dataSource` object to begin the local upload workflow:

{% code title="POST /customer/jobs/{jobId}/datasource" %}

```json
{
  "dataSource": {
    "dataSourceDescriptor": "file",
    "params": {
      "@type": "type.googleapis.com/bytenite.data_source.LocalFileDataSource"
    }
  }
}
```

{% endcode %}
{% endstep %}

{% step %}

### Retrieve a Temporary URL

After submitting the data source, fetch the generated temporary URL from the job's API response:

```python
temp_url = job_response.json()['job']['dataSource']['params']['tempUrl']
```

{% endstep %}

{% step %}

### Upload a File&#x20;

Upload your local file to the temp URL previously fetched using a PUT request:

```python
my_file = '/local/path/to/my/file.obj'

with open(my_file, mode='rb') as f:
    requests.put(temp_url, data=f, headers={'Content-Disposition': 'attachment'})
```

{% endstep %}

{% step %}

### Notify Server of Successful Upload

Let the server know that your upload is ready via the "Upload Completed" endpoint.

```python
response = requests.post(f'http://api.bytenite.com/v1/customer/jobs/uploadcompleted/{job_id}',
                                  json={}, headers={'Authorization': access_token})
```

This notification ends the workflow, linking the uploaded file to your job.
{% endstep %}
{% endstepper %}


# Temporary Bucket

With ByteNite, you can save your output files to a temporary storage location on Google Cloud at no additional cost.&#x20;

This temporary bucket is intended for short-term use and is automatically managed to ensure file security and accessibility. ByteNite generates a temporary authenticated direct access URL for each output file or folder, simplifying access to your results.&#x20;

Files remain available for **48 hours** after being saved in the temporary storage, after which they are permanently deleted. This setup is perfect for workflows requiring short-term file storage without ongoing management.

The temporary storage bucket is exclusively a **data destination**, designed for saving output files from your jobs. It cannot be used as a data origin for sourcing input files.

## Temporary Bucket Data Source Object

{% hint style="info" %}
`dataSourceDescriptor`  : **`bucket`**
{% endhint %}

To set up a temporary bucket data destination, provide the following simple dataSource object in your API request (no `params` expected):

{% code title="POST /customer/jobs/{jobId}/datasource" %}

```json
{
  "dataSource": {
    "dataSourceDescriptor": "bucket",
  }
}
```

{% endcode %}


# Jobs

A general guide for submitting jobs via API

Once your [Apps](/create-with-bytenite/building-blocks/apps), [Partitioning Engines](/create-with-bytenite/building-blocks/partitioning-engines), and [Assembling Engines](/create-with-bytenite/building-blocks/assembling-engines) are ready, and you've linked them together using [Job Templates](/create-with-bytenite/building-blocks/job-templates), you're prepared to launch test and production jobs.

ByteNite utilizes an API to handle job requests — the [Customer API](/api-reference/customer-api)— simplifying and standardizing the interaction with our server.

To begin using the API and familiarizing yourself with its endpoint, we recommend setting up a Postman collection. You can find more details at [Onboarding](/getting-started/onboarding#create-a-postman-collection-from-bytenites-oas).

Below are the steps to configure and send a new job request, broken down and explained. You may refer to the official [Jobs](/api-reference/customer-api/jobs) reference for a complete parameter list, response codes, and default code examples.

{% stepper %}
{% step %}

### Get an Access Token

Begin by obtaining a temporary access token to authenticate your requests.

{% tabs %}
{% tab title="Request URL" %} <mark style="color:yellow;">`POST`</mark> `https://api.bytenite.com/v1/auth/access_token`

***

*Main ref:* [Access Token](/api-reference/authentication-api/access-token#access_token)
{% endtab %}

{% tab title="Body" %}

| Name         | Type     | Description           |
| ------------ | -------- | --------------------- |
| `apiKey`     | *string* | Your ByteNite API Key |
| {% endtab %} |          |                       |

{% tab title="Response \[200]" %}

| Name          | Type     | Description                      |
| ------------- | -------- | -------------------------------- |
| `token`       | *string* | Your ByteNite access token       |
| `expiresIn`   | *string* | An expiration timeout in seconds |
| {% endtab %}  |          |                                  |
| {% endtabs %} |          |                                  |

Example:

{% code title="POST /auth/access\_token" %}

```python
import requests

response = requests.post(
    "https://api.bytenite.com/v1/auth/access_token",
    json = {
        "apiKey": "ey2WmEsSMK7wdxpK5MaEHXeWCD5KEJZ79Koe68yrHL4kdnnTXT01hu2iss43BdaCCMgJ3dBh2IOVCycTt1mwkT3QR1dLxRFpK7TW7ExvcuCXio6nKsGjk9dYY8nbsFffrUVvYSQYsuQoF3NIb8sS4MDyZfOgGKZL9z8x22cwrwEck7vIokVhQ9fyWRVU2vwRiX3X4bQFuqTkkWCi5Vfy8IkGkga7ZPMPb21FxqK6cHRJ3zmI1JZZoZZxERnQcWJTpZRyCP4SNTuRm3ueVDNntFqYWYYrseNLcCIS42MpR00Z9rI9I5xxuQD6VQvHVrpOaPucg1E4Vw54xXr2LKEy9uHcM5WUQHkdfhiXo6zyVbZMrbjLpepgeS4nEja="
    }
)

token = response.json()["token"]
```

{% endcode %}

{% endstep %}

{% step %}

### Create a New Job

Submit a new job request using an existing job template, and give it a name.

{% tabs %}
{% tab title="Request URL" %} <mark style="color:yellow;">`POST`</mark> `https://api.bytenite.com/v1/customer/jobs`

***

*Main ref:* [Create](/api-reference/customer-api/jobs/create#jobs)
{% endtab %}

{% tab title="Headers" %}

| Name            | Type     | Description                       |
| --------------- | -------- | --------------------------------- |
| `Authorization` | *string* | An active ByteNite access `token` |
| {% endtab %}    |          |                                   |

{% tab title="Body" %}

| Name          | Type     | Description                                   |
| ------------- | -------- | --------------------------------------------- |
| `templateId`  | *string* | ID of the job template used for this job      |
| `name`        | *string* | A descriptive name for your job               |
| `description` | *string* | An optional description with more information |
| {% endtab %}  |          |                                               |

{% tab title="Response \[200]" %}

| Name          | Type     | Description                                  |
| ------------- | -------- | -------------------------------------------- |
| `job`         | *object* | A job object, containing job metadata        |
| ↳ `id`        | *string* | The job identifier (automatically generated) |
| {% endtab %}  |          |                                              |
| {% endtabs %} |          |                                              |

Example:

{% code title="POST /customer/jobs" %}

```python
response = requests.post(
    "https://api.bytenite.com/v1/customer/jobs",
    headers = {
        "Authorization": token
    },
    json = {
        "name": "My job with img-gen-diffusers template",
        "templateId": "img-gen-diffusers"
    }
)

jobId = response.json()["job"]["id"]
```

{% endcode %}

{% endstep %}

{% step %}

### Submit a Data Source and Destination

Link a data source and destination to your job, specifying input and output options as documented in the [Data Sources](/launch-with-bytenite/data-sources) guide.

Connecting data sources is optional: if your app doesn't require any input data to work, or doesn't output data, you can specify a `bypass` data source descriptor.

{% tabs %}
{% tab title="Request URL" %} <mark style="color:purple;">`PATCH`</mark> `https://api.bytenite.com/v1/customer/jobs/{jobId}/datasource`

***

*Main ref:* [Update](/api-reference/customer-api/jobs/update#jobs-jobid-datasource)
{% endtab %}

{% tab title="Path Params" %}

| Name         | Type     | Description                |
| ------------ | -------- | -------------------------- |
| `jobId`      | *string* | The `jobId`of your new job |
| {% endtab %} |          |                            |

{% tab title="Headers" %}

| Name            | Type     | Description                       |
| --------------- | -------- | --------------------------------- |
| `Authorization` | *string* | An active ByteNite access `token` |
| {% endtab %}    |          |                                   |

{% tab title="Body" %}

| Name              | Type     | Description                                                                     |
| ----------------- | -------- | ------------------------------------------------------------------------------- |
| `dataSource`      | *object* | A data source object, containing a `dataSourceDescriptor` and optional `params` |
| `dataDestination` | *object* | A data source object, containing a `dataSourceDescriptor` and optional `params` |
| {% endtab %}      |          |                                                                                 |
| {% endtabs %}     |          |                                                                                 |

Example:

{% code title="PATCH /customer/jobs/{jobId}/datasource" %}

```python
response = requests.patch(
    f"https://api.bytenite.com/v1/customer/jobs/{jobId}/datasource",
    headers = {
        "Authorization": token
    },
    json = {  
        "dataSource": {
            "dataSourceDescriptor": "url",
            "params": {
                "@type": "type.googleapis.com/bytenite.data_source.HttpDataSource",
                "url": "https://storage.googleapis.com/my-public-bucket/my-input-file.txt"
            }
        },
        "dataDestination": {
            "dataSourceDescriptor": "bucket"
        }
    }
)
```

{% endcode %}

{% endstep %}

{% step %}

### Submit Job Parameters

If your app, partitioner, or assembler expect parameters, provide them at this step. Parameters are organized under three keys: `app`, `partitioner`, and `assembler` for clarity.

If your template includes parameter schemas, the parameters you submit here will be validated immediately, and any errors will be returned.

{% tabs %}
{% tab title="Request URL" %} <mark style="color:purple;">`PATCH`</mark> `https://api.bytenite.com/v1/customer/jobs/{jobId}/params`

***

*Main ref:* [Update](/api-reference/customer-api/jobs/update#jobs-jobid-params)
{% endtab %}

{% tab title="Path Params" %}

| Name         | Type     | Description                |
| ------------ | -------- | -------------------------- |
| `jobId`      | *string* | The `jobId`of your new job |
| {% endtab %} |          |                            |

{% tab title="Headers" %}

| Name            | Type     | Description                       |
| --------------- | -------- | --------------------------------- |
| `Authorization` | *string* | An active ByteNite access `token` |
| {% endtab %}    |          |                                   |

{% tab title="Body" %}

| Name          | Type     | Description                                                                 |
| ------------- | -------- | --------------------------------------------------------------------------- |
| `app`         | *object* | A JSON object containing parameters as expected by your app                 |
| `partitioner` | *object* | A JSON object containing parameters as expected by your partitioning engine |
| `assembler`   | *object* | A JSON object containing parameters as expected by your assembling engine   |
| {% endtab %}  |          |                                                                             |
| {% endtabs %} |          |                                                                             |

Example:

{% code title="PATCH /customer/jobs/{jobId}/params" %}

```python
response = requests.patch(
    f"https://api.bytenite.com/v1/customer/jobs/{jobId}/params",
    headers = {
        "Authorization": token
    },
    json = {
        "partitioner": {
            "numImages": 20
        },
        "app": {
            "prompt": "A beautiful sunset over the jungle"
        },
        "assembler": {
            "outExtension": "jpeg"
        }
    }
)
```

{% endcode %}

{% endstep %}

{% step %}

### Launch the Job

Run the job, including execution configurations if needed.&#x20;

Please note that you need this call to initiate the processing of your job. Without this step, your job will remain in a draft state.

{% tabs %}
{% tab title="Request URL" %} <mark style="color:yellow;">`POST`</mark> `https://api.bytenite.com/v1/customer/jobs/{jobId}/run`

***

*Main ref:* [Manage](/api-reference/customer-api/jobs/manage#jobs-jobid-run)
{% endtab %}

{% tab title="Path Params" %}

| Name         | Type     | Description                |
| ------------ | -------- | -------------------------- |
| `jobId`      | *string* | The `jobId`of your new job |
| {% endtab %} |          |                            |

{% tab title="Headers" %}

| Name            | Type     | Description                       |
| --------------- | -------- | --------------------------------- |
| `Authorization` | *string* | An active ByteNite access `token` |
| {% endtab %}    |          |                                   |

{% tab title="Body" %}

| Name          | Type      | Description                                                                                               |
| ------------- | --------- | --------------------------------------------------------------------------------------------------------- |
| `taskTimeout` | *integer* | An optional timeout for tasks, in seconds. After this time, a task will be stopped.                       |
| `jobTimeout`  | *integer* | An optional timeout for jobs, in seconds. After this time, the job and any running tasks will be stopped. |
| `isTestJob`   | *boolean* | A flag for test jobs.                                                                                     |
| {% endtab %}  |           |                                                                                                           |
| {% endtabs %} |           |                                                                                                           |

Example:

{% code title="PATCH /customer/jobs/{jobId}/params" %}

```python
response = requests.post(
    f"https://api.bytenite.com/v1/customer/jobs/{jobId}/run",
    headers = {
        "Authorization": token
    },
    json = {
        "taskTimeout": 3600,
        "jobTimeout": 86400,
        "isTestJob": True
    }
)
```

{% endcode %}

{% endstep %}
{% endstepper %}


# Observability

## Get logs

> Get logs for the provided filters

```json
{"openapi":"3.1.1","info":{"title":"ByteNite jobs API","version":"0.1"},"tags":[],"servers":[{"url":"https://api.bytenite.com/v1/customer"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"logsGetLogsResponse":{"type":"object","properties":{"partitioner":{"type":"array","items":{"$ref":"#/components/schemas/logsLogInstance"}},"assembler":{"type":"array","items":{"$ref":"#/components/schemas/logsLogInstance"}},"taskrunner":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/logsLogInstances"}}}},"logsLogInstance":{"type":"object","properties":{"log":{"type":"string","title":"The log message, this is the actual log message received from the loki server"},"timestamp":{"type":"string","format":"date-time","title":"The timestamp of the log message"},"level":{"$ref":"#/components/schemas/logsLogLevel","title":"The log level of the log message"},"container":{"type":"string","title":"Container name from which the log message was generated"}}},"logsLogLevel":{"type":"string","enum":["UNKNOWN","TRACE","DEBUG","INFO","WARN","ERROR","FATAL","PANIC"],"default":"UNKNOWN"},"logsLogInstances":{"type":"object","properties":{"logs":{"type":"array","items":{"$ref":"#/components/schemas/logsLogInstance"}}}},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}},"protobufAny":{"type":"object","properties":{"@type":{"type":"string"}},"additionalProperties":{}},"logsGetLogsRequest":{"type":"object","properties":{"jobId":{"type":"string","title":"The job id for which you want to get the logs"},"taskIds":{"type":"array","items":{"type":"string"},"title":"The task ids for which you want to get the logs"},"levels":{"type":"array","items":{"$ref":"#/components/schemas/logsLogLevel"},"title":"The log levels you want to get the logs for"},"services":{"type":"array","items":{"$ref":"#/components/schemas/logsLogService"},"title":"The services you want to get the logs for"}},"required":["jobId"]},"logsLogService":{"type":"string","enum":["PARTITIONER","ASSEMBLER","TASKRUNNER"],"default":"PARTITIONER"}}},"paths":{"/logs":{"post":{"summary":"Get logs","description":"Get logs for the provided filters","operationId":"Customer_GetLogs","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/logsGetLogsResponse"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/logsGetLogsResponse"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"tags":["Logs"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/logsGetLogsRequest"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/logsGetLogsRequest"}}},"required":true}}}}}
```


# Customer API

## About

* Base URL: `https://api.bytenite.com/v1/customer`
* Version: `v1`
* Swagger Docs: <https://api.bytenite.com/v1/customer/docs/>
* Specification: <https://api.bytenite.com/v1/customer/docs/swagger.json>

***

## Retrieve information about server

> Server software version and important messages

```json
{"openapi":"3.1.1","info":{"title":"ByteNite jobs API","version":"0.1"},"tags":[],"servers":[{"url":"https://api.bytenite.com/v1/customer"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"bytenitecustomerServerInfoResponse":{"type":"object","properties":{"version":{"$ref":"#/components/schemas/commonVersion"},"messages":{"type":"object","additionalProperties":{"type":"string"}}}},"commonVersion":{"type":"object","properties":{"major":{"type":"integer","format":"int64"},"minor":{"type":"integer","format":"int64"},"tag":{"type":"string"}},"description":"Version of the distributed app, including revision."},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}},"protobufAny":{"type":"object","properties":{"@type":{"type":"string"}},"additionalProperties":{}}}},"paths":{"/info":{"get":{"summary":"Retrieve information about server","description":"Server software version and important messages","operationId":"Customer_Info","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/bytenitecustomerServerInfoResponse"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/bytenitecustomerServerInfoResponse"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"tags":["Info"]}}}}
```


# Jobs

<table data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Create</strong></td><td>Post a new job.</td><td><a href="/api-reference/customer-api/jobs/create">Create</a></td></tr><tr><td><strong>Read</strong></td><td>Get a job's details, list and filter jobs.</td><td><a href="/api-reference/customer-api/jobs/read">Read</a></td></tr><tr><td><strong>Update</strong></td><td>Set a job's data source, parameters, and name.</td><td><a href="/api-reference/customer-api/jobs/update">Update</a></td></tr><tr><td><strong>Manage</strong></td><td>Run, abort, and delete jobs.</td><td><a href="/api-reference/customer-api/jobs/manage">Manage</a></td></tr></tbody></table>


# Create

***

## Create a new job

> Create a new computing job on ByteNite.

```json
{"openapi":"3.1.1","info":{"title":"ByteNite jobs API","version":"0.1"},"tags":[],"servers":[{"url":"https://api.bytenite.com/v1/customer"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"jobsJobResponse":{"type":"object","properties":{"job":{"$ref":"#/components/schemas/jobJob"},"templateInfo":{"$ref":"#/components/schemas/jobJobTemplate","title":"Job template information"}}},"jobJob":{"type":"object","properties":{"id":{"type":"string","title":"Unique id for the job","readOnly":true},"templateId":{"type":"string","title":"Job template to run"},"name":{"type":"string","title":"Human readable name"},"config":{"$ref":"#/components/schemas/jobJobConfig","title":"Job specific parameters"},"priority":{"$ref":"#/components/schemas/jobByteLevel","title":"Execution priority requirements for the job"},"startAt":{"type":"string","format":"date-time","title":"When the job should be run (0 for immediate start)"},"submittedAt":{"type":"string","format":"date-time","title":"Submission date/time for the job request","readOnly":true},"startedAt":{"type":"string","format":"date-time","title":"date/time of the first chunk upload","readOnly":true},"endedAt":{"type":"string","format":"date-time","title":"date/time of completion/failure","readOnly":true},"regions":{"$ref":"#/components/schemas/commonSelectionList","title":"Region to consider (or to exclude) for device selection"},"state":{"$ref":"#/components/schemas/jobJobState","title":"Current job state"},"dataSource":{"$ref":"#/components/schemas/data_sourceDataSource","title":"Input data source"},"params":{"$ref":"#/components/schemas/jobAppParams","description":"A JSON object that should be compatible with the JSONSchema associated to the Job Template specified in template_id","title":"App specific parameters passed to devices"},"dataDestination":{"$ref":"#/components/schemas/data_sourceDataSource","title":"Output data destination"},"duration":{"type":"number","format":"double","title":"Job duration in seconds","readOnly":true},"deletedAt":{"type":"string","format":"date-time","title":"Delete date/time for the job request","readOnly":true},"createdAt":{"type":"string","format":"date-time","title":"Creation time of the job","readOnly":true},"paymentAmount":{"type":"number","format":"double","readOnly":true},"numUnitsEstimation":{"type":"string","format":"int64","readOnly":true},"numChunks":{"type":"integer","format":"int32","readOnly":true},"errorMessage":{"type":"string","readOnly":true},"description":{"type":"string","title":"description of this job"},"stateTimestamps":{"type":"object","additionalProperties":{"type":"string","format":"date-time"},"title":"Timestamps for each state"},"appId":{"type":"string"},"templateInfo":{"$ref":"#/components/schemas/jobJobTemplate"}}},"jobJobConfig":{"type":"object","properties":{"taskTimeout":{"type":"integer","format":"int64","title":"task timeout in seconds"},"jobTimeout":{"type":"integer","format":"int64","title":"job timeout in seconds"},"isTestJob":{"type":"boolean","title":"'true' if this job is a test job"}}},"jobByteLevel":{"type":"string","enum":["EXECUTION_PRIORITY_UNDEFINED","EXECUTION_PRIORITY_CHEAP","EXECUTION_PRIORITY_BALANCED","EXECUTION_PRIORITY_FAST"],"default":"EXECUTION_PRIORITY_UNDEFINED"},"commonSelectionList":{"type":"object","properties":{"blacklist":{"type":"array","items":{"type":"string"}},"whitelist":{"type":"array","items":{"type":"string"}}}},"jobJobState":{"type":"string","enum":["JOB_STATE_NEW","JOB_STATE_STARTED","JOB_STATE_UPLOADING","JOB_STATE_PARTITIONING","JOB_STATE_PARTITIONED","JOB_STATE_TASKS_COMPLETED","JOB_STATE_MERGING","JOB_STATE_MERGED","JOB_STATE_DOWNLOADING","JOB_STATE_COMPLETE","JOB_STATE_FAILED"],"default":"JOB_STATE_NEW","description":" - JOB_STATE_NEW: The job has been created, and the user may still be updating its data sources and parameters.\n - JOB_STATE_STARTED: The job has begun execution after passing validation checks, including data sources, parameters, account balance, and grace period.\n - JOB_STATE_UPLOADING: The job has been retrieved from the partitioner’s job queue and is being sent to the appropriate partitioning engine. Reaching this state confirms the presence of a suitable partitioning engine.\n - JOB_STATE_PARTITIONING: The partitioning engine processes the job and generates multiple chunks, preparing them for further execution.\n - JOB_STATE_PARTITIONED: The partitioning engine has successfully divided the job into chunks, forwarding them to the feeder for distribution. Workers begin fetching and processing these chunks.\n - JOB_STATE_TASKS_COMPLETED: All assigned tasks have been successfully processed by the task runner\n - JOB_STATE_MERGING: The assembler engine retrieves and merges the processed data.\n - JOB_STATE_MERGED: The assembler engine has successfully completed merging the processed chunks. The final result is now prepared for uploading to the specified destination.\n - JOB_STATE_DOWNLOADING: The final output is being saved to the designated data destination.\n - JOB_STATE_COMPLETE: The job lifecycle is successfully completed, and the result has been uploaded to the specified destination.\n - JOB_STATE_FAILED: The job has encountered an error and failed to produce output."},"data_sourceDataSource":{"type":"object","properties":{"dataSourceDescriptor":{"type":"string","description":"Data source selector."},"params":{"$ref":"#/components/schemas/protobufAny","description":"Data source parameters."}},"description":"The data source object specifying configurations for inputs and outputs. Please refer to the dedicated guide for detailed instructions."},"protobufAny":{"type":"object","properties":{"@type":{"type":"string"}},"additionalProperties":{}},"jobAppParams":{"type":"object","properties":{"preset":{"type":"string","description":"[Deprecated] Preset configuration. This field is no longer in use."},"partitioner":{"type":"object","description":"Sets parameters for the partitioning engine."},"assembler":{"type":"object","description":"Sets parameters for the assembling engine."},"app":{"type":"object","description":"Sets parameters for the application.."}}},"jobJobTemplate":{"type":"object","properties":{"id":{"type":"string","title":"Unique ID for this Job Template (primary key)"},"owner":{"type":"string","title":"Owner of this Job Template (primary key)"},"description":{"type":"string","title":"Description of this Job Template"},"app":{"type":"string","title":"The application associated with this Job Template"},"partitioner":{"type":"string","title":"How data is partitioned"},"assembler":{"type":"string","title":"How data is assembled/merged"}}},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}},"jobsCreateJobRequest":{"type":"object","properties":{"name":{"type":"string","description":"Mnemonic name for the job."},"templateId":{"type":"string","description":"Identifier of the application template used for this job."},"description":{"type":"string","description":"Textual description of the job."},"dataSource":{"$ref":"#/components/schemas/data_sourceDataSource","description":"Configuration for the data source providing input data to the job."},"dataDestination":{"$ref":"#/components/schemas/data_sourceDataSource","description":"Configuration for the data destination where job output will be sent."},"params":{"$ref":"#/components/schemas/jobAppParams","description":"Job-specific configuration parameters for the distributed application."},"config":{"$ref":"#/components/schemas/jobJobConfig","description":"Job execution preferences."}},"required":["templateId"]}}},"paths":{"/jobs":{"post":{"summary":"Create a new job","description":"Create a new computing job on ByteNite.","operationId":"Customer_CreateJob","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/jobsJobResponse"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/jobsJobResponse"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"tags":["Jobs"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/jobsCreateJobRequest"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/jobsCreateJobRequest"}}},"required":true}}}}}
```


# Read

***

## Get job

> Get job properties

```json
{"openapi":"3.1.1","info":{"title":"ByteNite jobs API","version":"0.1"},"tags":[],"servers":[{"url":"https://api.bytenite.com/v1/customer"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"jobsJobResponse":{"type":"object","properties":{"job":{"$ref":"#/components/schemas/jobJob"},"templateInfo":{"$ref":"#/components/schemas/jobJobTemplate","title":"Job template information"}}},"jobJob":{"type":"object","properties":{"id":{"type":"string","title":"Unique id for the job","readOnly":true},"templateId":{"type":"string","title":"Job template to run"},"name":{"type":"string","title":"Human readable name"},"config":{"$ref":"#/components/schemas/jobJobConfig","title":"Job specific parameters"},"priority":{"$ref":"#/components/schemas/jobByteLevel","title":"Execution priority requirements for the job"},"startAt":{"type":"string","format":"date-time","title":"When the job should be run (0 for immediate start)"},"submittedAt":{"type":"string","format":"date-time","title":"Submission date/time for the job request","readOnly":true},"startedAt":{"type":"string","format":"date-time","title":"date/time of the first chunk upload","readOnly":true},"endedAt":{"type":"string","format":"date-time","title":"date/time of completion/failure","readOnly":true},"regions":{"$ref":"#/components/schemas/commonSelectionList","title":"Region to consider (or to exclude) for device selection"},"state":{"$ref":"#/components/schemas/jobJobState","title":"Current job state"},"dataSource":{"$ref":"#/components/schemas/data_sourceDataSource","title":"Input data source"},"params":{"$ref":"#/components/schemas/jobAppParams","description":"A JSON object that should be compatible with the JSONSchema associated to the Job Template specified in template_id","title":"App specific parameters passed to devices"},"dataDestination":{"$ref":"#/components/schemas/data_sourceDataSource","title":"Output data destination"},"duration":{"type":"number","format":"double","title":"Job duration in seconds","readOnly":true},"deletedAt":{"type":"string","format":"date-time","title":"Delete date/time for the job request","readOnly":true},"createdAt":{"type":"string","format":"date-time","title":"Creation time of the job","readOnly":true},"paymentAmount":{"type":"number","format":"double","readOnly":true},"numUnitsEstimation":{"type":"string","format":"int64","readOnly":true},"numChunks":{"type":"integer","format":"int32","readOnly":true},"errorMessage":{"type":"string","readOnly":true},"description":{"type":"string","title":"description of this job"},"stateTimestamps":{"type":"object","additionalProperties":{"type":"string","format":"date-time"},"title":"Timestamps for each state"},"appId":{"type":"string"},"templateInfo":{"$ref":"#/components/schemas/jobJobTemplate"}}},"jobJobConfig":{"type":"object","properties":{"taskTimeout":{"type":"integer","format":"int64","title":"task timeout in seconds"},"jobTimeout":{"type":"integer","format":"int64","title":"job timeout in seconds"},"isTestJob":{"type":"boolean","title":"'true' if this job is a test job"}}},"jobByteLevel":{"type":"string","enum":["EXECUTION_PRIORITY_UNDEFINED","EXECUTION_PRIORITY_CHEAP","EXECUTION_PRIORITY_BALANCED","EXECUTION_PRIORITY_FAST"],"default":"EXECUTION_PRIORITY_UNDEFINED"},"commonSelectionList":{"type":"object","properties":{"blacklist":{"type":"array","items":{"type":"string"}},"whitelist":{"type":"array","items":{"type":"string"}}}},"jobJobState":{"type":"string","enum":["JOB_STATE_NEW","JOB_STATE_STARTED","JOB_STATE_UPLOADING","JOB_STATE_PARTITIONING","JOB_STATE_PARTITIONED","JOB_STATE_TASKS_COMPLETED","JOB_STATE_MERGING","JOB_STATE_MERGED","JOB_STATE_DOWNLOADING","JOB_STATE_COMPLETE","JOB_STATE_FAILED"],"default":"JOB_STATE_NEW","description":" - JOB_STATE_NEW: The job has been created, and the user may still be updating its data sources and parameters.\n - JOB_STATE_STARTED: The job has begun execution after passing validation checks, including data sources, parameters, account balance, and grace period.\n - JOB_STATE_UPLOADING: The job has been retrieved from the partitioner’s job queue and is being sent to the appropriate partitioning engine. Reaching this state confirms the presence of a suitable partitioning engine.\n - JOB_STATE_PARTITIONING: The partitioning engine processes the job and generates multiple chunks, preparing them for further execution.\n - JOB_STATE_PARTITIONED: The partitioning engine has successfully divided the job into chunks, forwarding them to the feeder for distribution. Workers begin fetching and processing these chunks.\n - JOB_STATE_TASKS_COMPLETED: All assigned tasks have been successfully processed by the task runner\n - JOB_STATE_MERGING: The assembler engine retrieves and merges the processed data.\n - JOB_STATE_MERGED: The assembler engine has successfully completed merging the processed chunks. The final result is now prepared for uploading to the specified destination.\n - JOB_STATE_DOWNLOADING: The final output is being saved to the designated data destination.\n - JOB_STATE_COMPLETE: The job lifecycle is successfully completed, and the result has been uploaded to the specified destination.\n - JOB_STATE_FAILED: The job has encountered an error and failed to produce output."},"data_sourceDataSource":{"type":"object","properties":{"dataSourceDescriptor":{"type":"string","description":"Data source selector."},"params":{"$ref":"#/components/schemas/protobufAny","description":"Data source parameters."}},"description":"The data source object specifying configurations for inputs and outputs. Please refer to the dedicated guide for detailed instructions."},"protobufAny":{"type":"object","properties":{"@type":{"type":"string"}},"additionalProperties":{}},"jobAppParams":{"type":"object","properties":{"preset":{"type":"string","description":"[Deprecated] Preset configuration. This field is no longer in use."},"partitioner":{"type":"object","description":"Sets parameters for the partitioning engine."},"assembler":{"type":"object","description":"Sets parameters for the assembling engine."},"app":{"type":"object","description":"Sets parameters for the application.."}}},"jobJobTemplate":{"type":"object","properties":{"id":{"type":"string","title":"Unique ID for this Job Template (primary key)"},"owner":{"type":"string","title":"Owner of this Job Template (primary key)"},"description":{"type":"string","title":"Description of this Job Template"},"app":{"type":"string","title":"The application associated with this Job Template"},"partitioner":{"type":"string","title":"How data is partitioned"},"assembler":{"type":"string","title":"How data is assembled/merged"}}},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}}}},"paths":{"/jobs/{jobId}":{"get":{"summary":"Get job","description":"Get job properties","operationId":"Customer_GetJob","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/jobsJobResponse"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/jobsJobResponse"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"parameters":[{"schema":{"type":"string"},"name":"jobId","description":"The id associated with your job.","in":"path","required":true}],"tags":["Jobs"]}}}}
```

***

## Get results

> Get job results

```json
{"openapi":"3.1.1","info":{"title":"ByteNite jobs API","version":"0.1"},"tags":[],"servers":[{"url":"https://api.bytenite.com/v1/customer"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"jobsJobResultsResponse":{"type":"object","properties":{"results":{"type":"array","items":{"$ref":"#/components/schemas/jobsJobResult"}}}},"jobsJobResult":{"type":"object","properties":{"name":{"type":"string"},"link":{"type":"string"}}},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}},"protobufAny":{"type":"object","properties":{"@type":{"type":"string"}},"additionalProperties":{}}}},"paths":{"/jobs/{jobId}/results":{"get":{"summary":"Get results","description":"Get job results","operationId":"Customer_GetJobResults","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/jobsJobResultsResponse"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/jobsJobResultsResponse"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"parameters":[{"schema":{"type":"string"},"name":"jobId","description":"The id associated with your job.","in":"path","required":true}],"tags":["Jobs"]}}}}
```

***

## Get jobs

> Get all jobs for user with optional filters

```json
{"openapi":"3.1.1","info":{"title":"ByteNite jobs API","version":"0.1"},"tags":[],"servers":[{"url":"https://api.bytenite.com/v1/customer"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"jobsJobsResponse":{"type":"object","properties":{"pagination":{"$ref":"#/components/schemas/commonPaginatedResponse"},"data":{"type":"array","items":{"$ref":"#/components/schemas/jobJob"}}}},"commonPaginatedResponse":{"type":"object","properties":{"total":{"type":"integer","format":"int64","description":"The total number of transactions available."},"offset":{"type":"integer","format":"int64","description":"The starting position of the current page of results, starting from 0."},"hasPrevious":{"type":"boolean","description":"A boolean value (True/False) indicating whether there's a previous page of results. False if the current page is the first page."},"hasNext":{"type":"boolean","description":"A boolean value indicating whether there's a next page of results."}},"description":"This section provides information about how the results are divided into pages."},"jobJob":{"type":"object","properties":{"id":{"type":"string","title":"Unique id for the job","readOnly":true},"templateId":{"type":"string","title":"Job template to run"},"name":{"type":"string","title":"Human readable name"},"config":{"$ref":"#/components/schemas/jobJobConfig","title":"Job specific parameters"},"priority":{"$ref":"#/components/schemas/jobByteLevel","title":"Execution priority requirements for the job"},"startAt":{"type":"string","format":"date-time","title":"When the job should be run (0 for immediate start)"},"submittedAt":{"type":"string","format":"date-time","title":"Submission date/time for the job request","readOnly":true},"startedAt":{"type":"string","format":"date-time","title":"date/time of the first chunk upload","readOnly":true},"endedAt":{"type":"string","format":"date-time","title":"date/time of completion/failure","readOnly":true},"regions":{"$ref":"#/components/schemas/commonSelectionList","title":"Region to consider (or to exclude) for device selection"},"state":{"$ref":"#/components/schemas/jobJobState","title":"Current job state"},"dataSource":{"$ref":"#/components/schemas/data_sourceDataSource","title":"Input data source"},"params":{"$ref":"#/components/schemas/jobAppParams","description":"A JSON object that should be compatible with the JSONSchema associated to the Job Template specified in template_id","title":"App specific parameters passed to devices"},"dataDestination":{"$ref":"#/components/schemas/data_sourceDataSource","title":"Output data destination"},"duration":{"type":"number","format":"double","title":"Job duration in seconds","readOnly":true},"deletedAt":{"type":"string","format":"date-time","title":"Delete date/time for the job request","readOnly":true},"createdAt":{"type":"string","format":"date-time","title":"Creation time of the job","readOnly":true},"paymentAmount":{"type":"number","format":"double","readOnly":true},"numUnitsEstimation":{"type":"string","format":"int64","readOnly":true},"numChunks":{"type":"integer","format":"int32","readOnly":true},"errorMessage":{"type":"string","readOnly":true},"description":{"type":"string","title":"description of this job"},"stateTimestamps":{"type":"object","additionalProperties":{"type":"string","format":"date-time"},"title":"Timestamps for each state"},"appId":{"type":"string"},"templateInfo":{"$ref":"#/components/schemas/jobJobTemplate"}}},"jobJobConfig":{"type":"object","properties":{"taskTimeout":{"type":"integer","format":"int64","title":"task timeout in seconds"},"jobTimeout":{"type":"integer","format":"int64","title":"job timeout in seconds"},"isTestJob":{"type":"boolean","title":"'true' if this job is a test job"}}},"jobByteLevel":{"type":"string","enum":["EXECUTION_PRIORITY_UNDEFINED","EXECUTION_PRIORITY_CHEAP","EXECUTION_PRIORITY_BALANCED","EXECUTION_PRIORITY_FAST"],"default":"EXECUTION_PRIORITY_UNDEFINED"},"commonSelectionList":{"type":"object","properties":{"blacklist":{"type":"array","items":{"type":"string"}},"whitelist":{"type":"array","items":{"type":"string"}}}},"jobJobState":{"type":"string","enum":["JOB_STATE_NEW","JOB_STATE_STARTED","JOB_STATE_UPLOADING","JOB_STATE_PARTITIONING","JOB_STATE_PARTITIONED","JOB_STATE_TASKS_COMPLETED","JOB_STATE_MERGING","JOB_STATE_MERGED","JOB_STATE_DOWNLOADING","JOB_STATE_COMPLETE","JOB_STATE_FAILED"],"default":"JOB_STATE_NEW","description":" - JOB_STATE_NEW: The job has been created, and the user may still be updating its data sources and parameters.\n - JOB_STATE_STARTED: The job has begun execution after passing validation checks, including data sources, parameters, account balance, and grace period.\n - JOB_STATE_UPLOADING: The job has been retrieved from the partitioner’s job queue and is being sent to the appropriate partitioning engine. Reaching this state confirms the presence of a suitable partitioning engine.\n - JOB_STATE_PARTITIONING: The partitioning engine processes the job and generates multiple chunks, preparing them for further execution.\n - JOB_STATE_PARTITIONED: The partitioning engine has successfully divided the job into chunks, forwarding them to the feeder for distribution. Workers begin fetching and processing these chunks.\n - JOB_STATE_TASKS_COMPLETED: All assigned tasks have been successfully processed by the task runner\n - JOB_STATE_MERGING: The assembler engine retrieves and merges the processed data.\n - JOB_STATE_MERGED: The assembler engine has successfully completed merging the processed chunks. The final result is now prepared for uploading to the specified destination.\n - JOB_STATE_DOWNLOADING: The final output is being saved to the designated data destination.\n - JOB_STATE_COMPLETE: The job lifecycle is successfully completed, and the result has been uploaded to the specified destination.\n - JOB_STATE_FAILED: The job has encountered an error and failed to produce output."},"data_sourceDataSource":{"type":"object","properties":{"dataSourceDescriptor":{"type":"string","description":"Data source selector."},"params":{"$ref":"#/components/schemas/protobufAny","description":"Data source parameters."}},"description":"The data source object specifying configurations for inputs and outputs. Please refer to the dedicated guide for detailed instructions."},"protobufAny":{"type":"object","properties":{"@type":{"type":"string"}},"additionalProperties":{}},"jobAppParams":{"type":"object","properties":{"preset":{"type":"string","description":"[Deprecated] Preset configuration. This field is no longer in use."},"partitioner":{"type":"object","description":"Sets parameters for the partitioning engine."},"assembler":{"type":"object","description":"Sets parameters for the assembling engine."},"app":{"type":"object","description":"Sets parameters for the application.."}}},"jobJobTemplate":{"type":"object","properties":{"id":{"type":"string","title":"Unique ID for this Job Template (primary key)"},"owner":{"type":"string","title":"Owner of this Job Template (primary key)"},"description":{"type":"string","title":"Description of this Job Template"},"app":{"type":"string","title":"The application associated with this Job Template"},"partitioner":{"type":"string","title":"How data is partitioned"},"assembler":{"type":"string","title":"How data is assembled/merged"}}},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}}}},"paths":{"/jobs":{"get":{"summary":"Get jobs","description":"Get all jobs for user with optional filters","operationId":"Customer_GetAll","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/jobsJobsResponse"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/jobsJobsResponse"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"parameters":[{"schema":{"type":"integer","format":"int64"},"name":"pagination.limit","description":"Number of rows to return per page.","in":"query","required":false},{"schema":{"type":"integer","format":"int64"},"name":"pagination.offset","description":"Number of rows to skip before starting to collect the result set.","in":"query","required":false},{"schema":{"type":"string"},"name":"orderBy","in":"query","required":false}],"tags":["Jobs"]}}}}
```

***

## Get jobs filtered

> Get all jobs for user and filter them

```json
{"openapi":"3.1.1","info":{"title":"ByteNite jobs API","version":"0.1"},"tags":[],"servers":[{"url":"https://api.bytenite.com/v1/customer"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"jobsJobsResponse":{"type":"object","properties":{"pagination":{"$ref":"#/components/schemas/commonPaginatedResponse"},"data":{"type":"array","items":{"$ref":"#/components/schemas/jobJob"}}}},"commonPaginatedResponse":{"type":"object","properties":{"total":{"type":"integer","format":"int64","description":"The total number of transactions available."},"offset":{"type":"integer","format":"int64","description":"The starting position of the current page of results, starting from 0."},"hasPrevious":{"type":"boolean","description":"A boolean value (True/False) indicating whether there's a previous page of results. False if the current page is the first page."},"hasNext":{"type":"boolean","description":"A boolean value indicating whether there's a next page of results."}},"description":"This section provides information about how the results are divided into pages."},"jobJob":{"type":"object","properties":{"id":{"type":"string","title":"Unique id for the job","readOnly":true},"templateId":{"type":"string","title":"Job template to run"},"name":{"type":"string","title":"Human readable name"},"config":{"$ref":"#/components/schemas/jobJobConfig","title":"Job specific parameters"},"priority":{"$ref":"#/components/schemas/jobByteLevel","title":"Execution priority requirements for the job"},"startAt":{"type":"string","format":"date-time","title":"When the job should be run (0 for immediate start)"},"submittedAt":{"type":"string","format":"date-time","title":"Submission date/time for the job request","readOnly":true},"startedAt":{"type":"string","format":"date-time","title":"date/time of the first chunk upload","readOnly":true},"endedAt":{"type":"string","format":"date-time","title":"date/time of completion/failure","readOnly":true},"regions":{"$ref":"#/components/schemas/commonSelectionList","title":"Region to consider (or to exclude) for device selection"},"state":{"$ref":"#/components/schemas/jobJobState","title":"Current job state"},"dataSource":{"$ref":"#/components/schemas/data_sourceDataSource","title":"Input data source"},"params":{"$ref":"#/components/schemas/jobAppParams","description":"A JSON object that should be compatible with the JSONSchema associated to the Job Template specified in template_id","title":"App specific parameters passed to devices"},"dataDestination":{"$ref":"#/components/schemas/data_sourceDataSource","title":"Output data destination"},"duration":{"type":"number","format":"double","title":"Job duration in seconds","readOnly":true},"deletedAt":{"type":"string","format":"date-time","title":"Delete date/time for the job request","readOnly":true},"createdAt":{"type":"string","format":"date-time","title":"Creation time of the job","readOnly":true},"paymentAmount":{"type":"number","format":"double","readOnly":true},"numUnitsEstimation":{"type":"string","format":"int64","readOnly":true},"numChunks":{"type":"integer","format":"int32","readOnly":true},"errorMessage":{"type":"string","readOnly":true},"description":{"type":"string","title":"description of this job"},"stateTimestamps":{"type":"object","additionalProperties":{"type":"string","format":"date-time"},"title":"Timestamps for each state"},"appId":{"type":"string"},"templateInfo":{"$ref":"#/components/schemas/jobJobTemplate"}}},"jobJobConfig":{"type":"object","properties":{"taskTimeout":{"type":"integer","format":"int64","title":"task timeout in seconds"},"jobTimeout":{"type":"integer","format":"int64","title":"job timeout in seconds"},"isTestJob":{"type":"boolean","title":"'true' if this job is a test job"}}},"jobByteLevel":{"type":"string","enum":["EXECUTION_PRIORITY_UNDEFINED","EXECUTION_PRIORITY_CHEAP","EXECUTION_PRIORITY_BALANCED","EXECUTION_PRIORITY_FAST"],"default":"EXECUTION_PRIORITY_UNDEFINED"},"commonSelectionList":{"type":"object","properties":{"blacklist":{"type":"array","items":{"type":"string"}},"whitelist":{"type":"array","items":{"type":"string"}}}},"jobJobState":{"type":"string","enum":["JOB_STATE_NEW","JOB_STATE_STARTED","JOB_STATE_UPLOADING","JOB_STATE_PARTITIONING","JOB_STATE_PARTITIONED","JOB_STATE_TASKS_COMPLETED","JOB_STATE_MERGING","JOB_STATE_MERGED","JOB_STATE_DOWNLOADING","JOB_STATE_COMPLETE","JOB_STATE_FAILED"],"default":"JOB_STATE_NEW","description":" - JOB_STATE_NEW: The job has been created, and the user may still be updating its data sources and parameters.\n - JOB_STATE_STARTED: The job has begun execution after passing validation checks, including data sources, parameters, account balance, and grace period.\n - JOB_STATE_UPLOADING: The job has been retrieved from the partitioner’s job queue and is being sent to the appropriate partitioning engine. Reaching this state confirms the presence of a suitable partitioning engine.\n - JOB_STATE_PARTITIONING: The partitioning engine processes the job and generates multiple chunks, preparing them for further execution.\n - JOB_STATE_PARTITIONED: The partitioning engine has successfully divided the job into chunks, forwarding them to the feeder for distribution. Workers begin fetching and processing these chunks.\n - JOB_STATE_TASKS_COMPLETED: All assigned tasks have been successfully processed by the task runner\n - JOB_STATE_MERGING: The assembler engine retrieves and merges the processed data.\n - JOB_STATE_MERGED: The assembler engine has successfully completed merging the processed chunks. The final result is now prepared for uploading to the specified destination.\n - JOB_STATE_DOWNLOADING: The final output is being saved to the designated data destination.\n - JOB_STATE_COMPLETE: The job lifecycle is successfully completed, and the result has been uploaded to the specified destination.\n - JOB_STATE_FAILED: The job has encountered an error and failed to produce output."},"data_sourceDataSource":{"type":"object","properties":{"dataSourceDescriptor":{"type":"string","description":"Data source selector."},"params":{"$ref":"#/components/schemas/protobufAny","description":"Data source parameters."}},"description":"The data source object specifying configurations for inputs and outputs. Please refer to the dedicated guide for detailed instructions."},"protobufAny":{"type":"object","properties":{"@type":{"type":"string"}},"additionalProperties":{}},"jobAppParams":{"type":"object","properties":{"preset":{"type":"string","description":"[Deprecated] Preset configuration. This field is no longer in use."},"partitioner":{"type":"object","description":"Sets parameters for the partitioning engine."},"assembler":{"type":"object","description":"Sets parameters for the assembling engine."},"app":{"type":"object","description":"Sets parameters for the application.."}}},"jobJobTemplate":{"type":"object","properties":{"id":{"type":"string","title":"Unique ID for this Job Template (primary key)"},"owner":{"type":"string","title":"Owner of this Job Template (primary key)"},"description":{"type":"string","title":"Description of this Job Template"},"app":{"type":"string","title":"The application associated with this Job Template"},"partitioner":{"type":"string","title":"How data is partitioned"},"assembler":{"type":"string","title":"How data is assembled/merged"}}},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}},"customerGetAllJobsRequest":{"type":"object","properties":{"pagination":{"$ref":"#/components/schemas/commonLimitOffsetPagination"},"filters":{"type":"array","items":{"$ref":"#/components/schemas/commonFilter"}},"orderBy":{"type":"string"}}},"commonLimitOffsetPagination":{"type":"object","properties":{"limit":{"type":"integer","format":"int64","description":"Number of rows to return per page."},"offset":{"type":"integer","format":"int64","description":"Number of rows to skip before starting to collect the result set."}}},"commonFilter":{"type":"object","properties":{"field":{"type":"string","description":"The field to apply the filter on"},"condition":{"$ref":"#/components/schemas/commonFilterCondition","description":"The condition to apply"},"value":{"type":"object","$ref":"#/components/schemas/protobufAny","description":"The value to filter on. Can be any type."}}},"commonFilterCondition":{"type":"string","enum":["FILTER_CONDITION_EQ","FILTER_CONDITION_NEQ","FILTER_CONDITION_GT","FILTER_CONDITION_GTE","FILTER_CONDITION_LT","FILTER_CONDITION_LTE","FILTER_CONDITION_ARRAY_CONTAINS","FILTER_CONDITION_ARRAY_CONTAINS_ANY","FILTER_CONDITION_IN","FILTER_CONDITION_NOT_IN","FILTER_CONDITION_LIKE"],"default":"FILTER_CONDITION_EQ"}}},"paths":{"/jobs/filter":{"post":{"summary":"Get jobs filtered","description":"Get all jobs for user and filter them","operationId":"Customer_GetAllFiltered","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/jobsJobsResponse"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/jobsJobsResponse"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"tags":["Jobs"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/customerGetAllJobsRequest"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/customerGetAllJobsRequest"}}},"required":true}}}}}
```


# Update

***

## Set a job datasource

> Set a job datasource

```json
{"openapi":"3.1.1","info":{"title":"ByteNite jobs API","version":"0.1"},"tags":[],"servers":[{"url":"https://api.bytenite.com/v1/customer"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"jobsJobResponse":{"type":"object","properties":{"job":{"$ref":"#/components/schemas/jobJob"},"templateInfo":{"$ref":"#/components/schemas/jobJobTemplate","title":"Job template information"}}},"jobJob":{"type":"object","properties":{"id":{"type":"string","title":"Unique id for the job","readOnly":true},"templateId":{"type":"string","title":"Job template to run"},"name":{"type":"string","title":"Human readable name"},"config":{"$ref":"#/components/schemas/jobJobConfig","title":"Job specific parameters"},"priority":{"$ref":"#/components/schemas/jobByteLevel","title":"Execution priority requirements for the job"},"startAt":{"type":"string","format":"date-time","title":"When the job should be run (0 for immediate start)"},"submittedAt":{"type":"string","format":"date-time","title":"Submission date/time for the job request","readOnly":true},"startedAt":{"type":"string","format":"date-time","title":"date/time of the first chunk upload","readOnly":true},"endedAt":{"type":"string","format":"date-time","title":"date/time of completion/failure","readOnly":true},"regions":{"$ref":"#/components/schemas/commonSelectionList","title":"Region to consider (or to exclude) for device selection"},"state":{"$ref":"#/components/schemas/jobJobState","title":"Current job state"},"dataSource":{"$ref":"#/components/schemas/data_sourceDataSource","title":"Input data source"},"params":{"$ref":"#/components/schemas/jobAppParams","description":"A JSON object that should be compatible with the JSONSchema associated to the Job Template specified in template_id","title":"App specific parameters passed to devices"},"dataDestination":{"$ref":"#/components/schemas/data_sourceDataSource","title":"Output data destination"},"duration":{"type":"number","format":"double","title":"Job duration in seconds","readOnly":true},"deletedAt":{"type":"string","format":"date-time","title":"Delete date/time for the job request","readOnly":true},"createdAt":{"type":"string","format":"date-time","title":"Creation time of the job","readOnly":true},"paymentAmount":{"type":"number","format":"double","readOnly":true},"numUnitsEstimation":{"type":"string","format":"int64","readOnly":true},"numChunks":{"type":"integer","format":"int32","readOnly":true},"errorMessage":{"type":"string","readOnly":true},"description":{"type":"string","title":"description of this job"},"stateTimestamps":{"type":"object","additionalProperties":{"type":"string","format":"date-time"},"title":"Timestamps for each state"},"appId":{"type":"string"},"templateInfo":{"$ref":"#/components/schemas/jobJobTemplate"}}},"jobJobConfig":{"type":"object","properties":{"taskTimeout":{"type":"integer","format":"int64","title":"task timeout in seconds"},"jobTimeout":{"type":"integer","format":"int64","title":"job timeout in seconds"},"isTestJob":{"type":"boolean","title":"'true' if this job is a test job"}}},"jobByteLevel":{"type":"string","enum":["EXECUTION_PRIORITY_UNDEFINED","EXECUTION_PRIORITY_CHEAP","EXECUTION_PRIORITY_BALANCED","EXECUTION_PRIORITY_FAST"],"default":"EXECUTION_PRIORITY_UNDEFINED"},"commonSelectionList":{"type":"object","properties":{"blacklist":{"type":"array","items":{"type":"string"}},"whitelist":{"type":"array","items":{"type":"string"}}}},"jobJobState":{"type":"string","enum":["JOB_STATE_NEW","JOB_STATE_STARTED","JOB_STATE_UPLOADING","JOB_STATE_PARTITIONING","JOB_STATE_PARTITIONED","JOB_STATE_TASKS_COMPLETED","JOB_STATE_MERGING","JOB_STATE_MERGED","JOB_STATE_DOWNLOADING","JOB_STATE_COMPLETE","JOB_STATE_FAILED"],"default":"JOB_STATE_NEW","description":" - JOB_STATE_NEW: The job has been created, and the user may still be updating its data sources and parameters.\n - JOB_STATE_STARTED: The job has begun execution after passing validation checks, including data sources, parameters, account balance, and grace period.\n - JOB_STATE_UPLOADING: The job has been retrieved from the partitioner’s job queue and is being sent to the appropriate partitioning engine. Reaching this state confirms the presence of a suitable partitioning engine.\n - JOB_STATE_PARTITIONING: The partitioning engine processes the job and generates multiple chunks, preparing them for further execution.\n - JOB_STATE_PARTITIONED: The partitioning engine has successfully divided the job into chunks, forwarding them to the feeder for distribution. Workers begin fetching and processing these chunks.\n - JOB_STATE_TASKS_COMPLETED: All assigned tasks have been successfully processed by the task runner\n - JOB_STATE_MERGING: The assembler engine retrieves and merges the processed data.\n - JOB_STATE_MERGED: The assembler engine has successfully completed merging the processed chunks. The final result is now prepared for uploading to the specified destination.\n - JOB_STATE_DOWNLOADING: The final output is being saved to the designated data destination.\n - JOB_STATE_COMPLETE: The job lifecycle is successfully completed, and the result has been uploaded to the specified destination.\n - JOB_STATE_FAILED: The job has encountered an error and failed to produce output."},"data_sourceDataSource":{"type":"object","properties":{"dataSourceDescriptor":{"type":"string","description":"Data source selector."},"params":{"$ref":"#/components/schemas/protobufAny","description":"Data source parameters."}},"description":"The data source object specifying configurations for inputs and outputs. Please refer to the dedicated guide for detailed instructions."},"protobufAny":{"type":"object","properties":{"@type":{"type":"string"}},"additionalProperties":{}},"jobAppParams":{"type":"object","properties":{"preset":{"type":"string","description":"[Deprecated] Preset configuration. This field is no longer in use."},"partitioner":{"type":"object","description":"Sets parameters for the partitioning engine."},"assembler":{"type":"object","description":"Sets parameters for the assembling engine."},"app":{"type":"object","description":"Sets parameters for the application.."}}},"jobJobTemplate":{"type":"object","properties":{"id":{"type":"string","title":"Unique ID for this Job Template (primary key)"},"owner":{"type":"string","title":"Owner of this Job Template (primary key)"},"description":{"type":"string","title":"Description of this Job Template"},"app":{"type":"string","title":"The application associated with this Job Template"},"partitioner":{"type":"string","title":"How data is partitioned"},"assembler":{"type":"string","title":"How data is assembled/merged"}}},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}},"jobsDataSourceParams":{"type":"object","properties":{"dataSource":{"$ref":"#/components/schemas/data_sourceDataSource"},"dataDestination":{"$ref":"#/components/schemas/data_sourceDataSource"}}}}},"paths":{"/jobs/{jobId}/datasource":{"patch":{"summary":"Set a job datasource","description":"Set a job datasource","operationId":"Customer_SetJobDataSource","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/jobsJobResponse"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/jobsJobResponse"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"parameters":[{"schema":{"type":"string"},"name":"jobId","description":"The id associated with your job.","in":"path","required":true}],"tags":["Jobs"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/jobsDataSourceParams"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/jobsDataSourceParams"}}},"required":true}}}}}
```

***

## Set job parameters

> Set or update job specific parameters

```json
{"openapi":"3.1.1","info":{"title":"ByteNite jobs API","version":"0.1"},"tags":[],"servers":[{"url":"https://api.bytenite.com/v1/customer"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"jobsJobResponse":{"type":"object","properties":{"job":{"$ref":"#/components/schemas/jobJob"},"templateInfo":{"$ref":"#/components/schemas/jobJobTemplate","title":"Job template information"}}},"jobJob":{"type":"object","properties":{"id":{"type":"string","title":"Unique id for the job","readOnly":true},"templateId":{"type":"string","title":"Job template to run"},"name":{"type":"string","title":"Human readable name"},"config":{"$ref":"#/components/schemas/jobJobConfig","title":"Job specific parameters"},"priority":{"$ref":"#/components/schemas/jobByteLevel","title":"Execution priority requirements for the job"},"startAt":{"type":"string","format":"date-time","title":"When the job should be run (0 for immediate start)"},"submittedAt":{"type":"string","format":"date-time","title":"Submission date/time for the job request","readOnly":true},"startedAt":{"type":"string","format":"date-time","title":"date/time of the first chunk upload","readOnly":true},"endedAt":{"type":"string","format":"date-time","title":"date/time of completion/failure","readOnly":true},"regions":{"$ref":"#/components/schemas/commonSelectionList","title":"Region to consider (or to exclude) for device selection"},"state":{"$ref":"#/components/schemas/jobJobState","title":"Current job state"},"dataSource":{"$ref":"#/components/schemas/data_sourceDataSource","title":"Input data source"},"params":{"$ref":"#/components/schemas/jobAppParams","description":"A JSON object that should be compatible with the JSONSchema associated to the Job Template specified in template_id","title":"App specific parameters passed to devices"},"dataDestination":{"$ref":"#/components/schemas/data_sourceDataSource","title":"Output data destination"},"duration":{"type":"number","format":"double","title":"Job duration in seconds","readOnly":true},"deletedAt":{"type":"string","format":"date-time","title":"Delete date/time for the job request","readOnly":true},"createdAt":{"type":"string","format":"date-time","title":"Creation time of the job","readOnly":true},"paymentAmount":{"type":"number","format":"double","readOnly":true},"numUnitsEstimation":{"type":"string","format":"int64","readOnly":true},"numChunks":{"type":"integer","format":"int32","readOnly":true},"errorMessage":{"type":"string","readOnly":true},"description":{"type":"string","title":"description of this job"},"stateTimestamps":{"type":"object","additionalProperties":{"type":"string","format":"date-time"},"title":"Timestamps for each state"},"appId":{"type":"string"},"templateInfo":{"$ref":"#/components/schemas/jobJobTemplate"}}},"jobJobConfig":{"type":"object","properties":{"taskTimeout":{"type":"integer","format":"int64","title":"task timeout in seconds"},"jobTimeout":{"type":"integer","format":"int64","title":"job timeout in seconds"},"isTestJob":{"type":"boolean","title":"'true' if this job is a test job"}}},"jobByteLevel":{"type":"string","enum":["EXECUTION_PRIORITY_UNDEFINED","EXECUTION_PRIORITY_CHEAP","EXECUTION_PRIORITY_BALANCED","EXECUTION_PRIORITY_FAST"],"default":"EXECUTION_PRIORITY_UNDEFINED"},"commonSelectionList":{"type":"object","properties":{"blacklist":{"type":"array","items":{"type":"string"}},"whitelist":{"type":"array","items":{"type":"string"}}}},"jobJobState":{"type":"string","enum":["JOB_STATE_NEW","JOB_STATE_STARTED","JOB_STATE_UPLOADING","JOB_STATE_PARTITIONING","JOB_STATE_PARTITIONED","JOB_STATE_TASKS_COMPLETED","JOB_STATE_MERGING","JOB_STATE_MERGED","JOB_STATE_DOWNLOADING","JOB_STATE_COMPLETE","JOB_STATE_FAILED"],"default":"JOB_STATE_NEW","description":" - JOB_STATE_NEW: The job has been created, and the user may still be updating its data sources and parameters.\n - JOB_STATE_STARTED: The job has begun execution after passing validation checks, including data sources, parameters, account balance, and grace period.\n - JOB_STATE_UPLOADING: The job has been retrieved from the partitioner’s job queue and is being sent to the appropriate partitioning engine. Reaching this state confirms the presence of a suitable partitioning engine.\n - JOB_STATE_PARTITIONING: The partitioning engine processes the job and generates multiple chunks, preparing them for further execution.\n - JOB_STATE_PARTITIONED: The partitioning engine has successfully divided the job into chunks, forwarding them to the feeder for distribution. Workers begin fetching and processing these chunks.\n - JOB_STATE_TASKS_COMPLETED: All assigned tasks have been successfully processed by the task runner\n - JOB_STATE_MERGING: The assembler engine retrieves and merges the processed data.\n - JOB_STATE_MERGED: The assembler engine has successfully completed merging the processed chunks. The final result is now prepared for uploading to the specified destination.\n - JOB_STATE_DOWNLOADING: The final output is being saved to the designated data destination.\n - JOB_STATE_COMPLETE: The job lifecycle is successfully completed, and the result has been uploaded to the specified destination.\n - JOB_STATE_FAILED: The job has encountered an error and failed to produce output."},"data_sourceDataSource":{"type":"object","properties":{"dataSourceDescriptor":{"type":"string","description":"Data source selector."},"params":{"$ref":"#/components/schemas/protobufAny","description":"Data source parameters."}},"description":"The data source object specifying configurations for inputs and outputs. Please refer to the dedicated guide for detailed instructions."},"protobufAny":{"type":"object","properties":{"@type":{"type":"string"}},"additionalProperties":{}},"jobAppParams":{"type":"object","properties":{"preset":{"type":"string","description":"[Deprecated] Preset configuration. This field is no longer in use."},"partitioner":{"type":"object","description":"Sets parameters for the partitioning engine."},"assembler":{"type":"object","description":"Sets parameters for the assembling engine."},"app":{"type":"object","description":"Sets parameters for the application.."}}},"jobJobTemplate":{"type":"object","properties":{"id":{"type":"string","title":"Unique ID for this Job Template (primary key)"},"owner":{"type":"string","title":"Owner of this Job Template (primary key)"},"description":{"type":"string","title":"Description of this Job Template"},"app":{"type":"string","title":"The application associated with this Job Template"},"partitioner":{"type":"string","title":"How data is partitioned"},"assembler":{"type":"string","title":"How data is assembled/merged"}}},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}}}},"paths":{"/jobs/{jobId}/params":{"patch":{"summary":"Set job parameters","description":"Set or update job specific parameters","operationId":"Customer_SetJobParams","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/jobsJobResponse"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/jobsJobResponse"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"parameters":[{"schema":{"type":"string"},"name":"jobId","description":"The id associated with your job.","in":"path","required":true}],"tags":["Jobs"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/jobAppParams"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/jobAppParams"}}},"required":true}}}}}
```

***

## Set a job name

> Set a job name

```json
{"openapi":"3.1.1","info":{"title":"ByteNite jobs API","version":"0.1"},"tags":[],"servers":[{"url":"https://api.bytenite.com/v1/customer"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"jobsJobResponse":{"type":"object","properties":{"job":{"$ref":"#/components/schemas/jobJob"},"templateInfo":{"$ref":"#/components/schemas/jobJobTemplate","title":"Job template information"}}},"jobJob":{"type":"object","properties":{"id":{"type":"string","title":"Unique id for the job","readOnly":true},"templateId":{"type":"string","title":"Job template to run"},"name":{"type":"string","title":"Human readable name"},"config":{"$ref":"#/components/schemas/jobJobConfig","title":"Job specific parameters"},"priority":{"$ref":"#/components/schemas/jobByteLevel","title":"Execution priority requirements for the job"},"startAt":{"type":"string","format":"date-time","title":"When the job should be run (0 for immediate start)"},"submittedAt":{"type":"string","format":"date-time","title":"Submission date/time for the job request","readOnly":true},"startedAt":{"type":"string","format":"date-time","title":"date/time of the first chunk upload","readOnly":true},"endedAt":{"type":"string","format":"date-time","title":"date/time of completion/failure","readOnly":true},"regions":{"$ref":"#/components/schemas/commonSelectionList","title":"Region to consider (or to exclude) for device selection"},"state":{"$ref":"#/components/schemas/jobJobState","title":"Current job state"},"dataSource":{"$ref":"#/components/schemas/data_sourceDataSource","title":"Input data source"},"params":{"$ref":"#/components/schemas/jobAppParams","description":"A JSON object that should be compatible with the JSONSchema associated to the Job Template specified in template_id","title":"App specific parameters passed to devices"},"dataDestination":{"$ref":"#/components/schemas/data_sourceDataSource","title":"Output data destination"},"duration":{"type":"number","format":"double","title":"Job duration in seconds","readOnly":true},"deletedAt":{"type":"string","format":"date-time","title":"Delete date/time for the job request","readOnly":true},"createdAt":{"type":"string","format":"date-time","title":"Creation time of the job","readOnly":true},"paymentAmount":{"type":"number","format":"double","readOnly":true},"numUnitsEstimation":{"type":"string","format":"int64","readOnly":true},"numChunks":{"type":"integer","format":"int32","readOnly":true},"errorMessage":{"type":"string","readOnly":true},"description":{"type":"string","title":"description of this job"},"stateTimestamps":{"type":"object","additionalProperties":{"type":"string","format":"date-time"},"title":"Timestamps for each state"},"appId":{"type":"string"},"templateInfo":{"$ref":"#/components/schemas/jobJobTemplate"}}},"jobJobConfig":{"type":"object","properties":{"taskTimeout":{"type":"integer","format":"int64","title":"task timeout in seconds"},"jobTimeout":{"type":"integer","format":"int64","title":"job timeout in seconds"},"isTestJob":{"type":"boolean","title":"'true' if this job is a test job"}}},"jobByteLevel":{"type":"string","enum":["EXECUTION_PRIORITY_UNDEFINED","EXECUTION_PRIORITY_CHEAP","EXECUTION_PRIORITY_BALANCED","EXECUTION_PRIORITY_FAST"],"default":"EXECUTION_PRIORITY_UNDEFINED"},"commonSelectionList":{"type":"object","properties":{"blacklist":{"type":"array","items":{"type":"string"}},"whitelist":{"type":"array","items":{"type":"string"}}}},"jobJobState":{"type":"string","enum":["JOB_STATE_NEW","JOB_STATE_STARTED","JOB_STATE_UPLOADING","JOB_STATE_PARTITIONING","JOB_STATE_PARTITIONED","JOB_STATE_TASKS_COMPLETED","JOB_STATE_MERGING","JOB_STATE_MERGED","JOB_STATE_DOWNLOADING","JOB_STATE_COMPLETE","JOB_STATE_FAILED"],"default":"JOB_STATE_NEW","description":" - JOB_STATE_NEW: The job has been created, and the user may still be updating its data sources and parameters.\n - JOB_STATE_STARTED: The job has begun execution after passing validation checks, including data sources, parameters, account balance, and grace period.\n - JOB_STATE_UPLOADING: The job has been retrieved from the partitioner’s job queue and is being sent to the appropriate partitioning engine. Reaching this state confirms the presence of a suitable partitioning engine.\n - JOB_STATE_PARTITIONING: The partitioning engine processes the job and generates multiple chunks, preparing them for further execution.\n - JOB_STATE_PARTITIONED: The partitioning engine has successfully divided the job into chunks, forwarding them to the feeder for distribution. Workers begin fetching and processing these chunks.\n - JOB_STATE_TASKS_COMPLETED: All assigned tasks have been successfully processed by the task runner\n - JOB_STATE_MERGING: The assembler engine retrieves and merges the processed data.\n - JOB_STATE_MERGED: The assembler engine has successfully completed merging the processed chunks. The final result is now prepared for uploading to the specified destination.\n - JOB_STATE_DOWNLOADING: The final output is being saved to the designated data destination.\n - JOB_STATE_COMPLETE: The job lifecycle is successfully completed, and the result has been uploaded to the specified destination.\n - JOB_STATE_FAILED: The job has encountered an error and failed to produce output."},"data_sourceDataSource":{"type":"object","properties":{"dataSourceDescriptor":{"type":"string","description":"Data source selector."},"params":{"$ref":"#/components/schemas/protobufAny","description":"Data source parameters."}},"description":"The data source object specifying configurations for inputs and outputs. Please refer to the dedicated guide for detailed instructions."},"protobufAny":{"type":"object","properties":{"@type":{"type":"string"}},"additionalProperties":{}},"jobAppParams":{"type":"object","properties":{"preset":{"type":"string","description":"[Deprecated] Preset configuration. This field is no longer in use."},"partitioner":{"type":"object","description":"Sets parameters for the partitioning engine."},"assembler":{"type":"object","description":"Sets parameters for the assembling engine."},"app":{"type":"object","description":"Sets parameters for the application.."}}},"jobJobTemplate":{"type":"object","properties":{"id":{"type":"string","title":"Unique ID for this Job Template (primary key)"},"owner":{"type":"string","title":"Owner of this Job Template (primary key)"},"description":{"type":"string","title":"Description of this Job Template"},"app":{"type":"string","title":"The application associated with this Job Template"},"partitioner":{"type":"string","title":"How data is partitioned"},"assembler":{"type":"string","title":"How data is assembled/merged"}}},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}}}},"paths":{"/jobs/{jobId}/jobname":{"patch":{"summary":"Set a job name","description":"Set a job name","operationId":"Customer_SetJobName","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/jobsJobResponse"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/jobsJobResponse"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"parameters":[{"schema":{"type":"string"},"name":"jobId","description":"The id associated with your job.","in":"path","required":true}],"tags":["Jobs"],"requestBody":{"content":{"application/json":{"schema":{"type":"string"}},"application/x-protobuf":{"schema":{"type":"string"}}},"description":"A descriptive name for your job.","required":true}}}}}
```

***

## Set job configs

> Set or update execution parameters/configurations

```json
{"openapi":"3.1.1","info":{"title":"ByteNite jobs API","version":"0.1"},"tags":[],"servers":[{"url":"https://api.bytenite.com/v1/customer"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"jobsJobResponse":{"type":"object","properties":{"job":{"$ref":"#/components/schemas/jobJob"},"templateInfo":{"$ref":"#/components/schemas/jobJobTemplate","title":"Job template information"}}},"jobJob":{"type":"object","properties":{"id":{"type":"string","title":"Unique id for the job","readOnly":true},"templateId":{"type":"string","title":"Job template to run"},"name":{"type":"string","title":"Human readable name"},"config":{"$ref":"#/components/schemas/jobJobConfig","title":"Job specific parameters"},"priority":{"$ref":"#/components/schemas/jobByteLevel","title":"Execution priority requirements for the job"},"startAt":{"type":"string","format":"date-time","title":"When the job should be run (0 for immediate start)"},"submittedAt":{"type":"string","format":"date-time","title":"Submission date/time for the job request","readOnly":true},"startedAt":{"type":"string","format":"date-time","title":"date/time of the first chunk upload","readOnly":true},"endedAt":{"type":"string","format":"date-time","title":"date/time of completion/failure","readOnly":true},"regions":{"$ref":"#/components/schemas/commonSelectionList","title":"Region to consider (or to exclude) for device selection"},"state":{"$ref":"#/components/schemas/jobJobState","title":"Current job state"},"dataSource":{"$ref":"#/components/schemas/data_sourceDataSource","title":"Input data source"},"params":{"$ref":"#/components/schemas/jobAppParams","description":"A JSON object that should be compatible with the JSONSchema associated to the Job Template specified in template_id","title":"App specific parameters passed to devices"},"dataDestination":{"$ref":"#/components/schemas/data_sourceDataSource","title":"Output data destination"},"duration":{"type":"number","format":"double","title":"Job duration in seconds","readOnly":true},"deletedAt":{"type":"string","format":"date-time","title":"Delete date/time for the job request","readOnly":true},"createdAt":{"type":"string","format":"date-time","title":"Creation time of the job","readOnly":true},"paymentAmount":{"type":"number","format":"double","readOnly":true},"numUnitsEstimation":{"type":"string","format":"int64","readOnly":true},"numChunks":{"type":"integer","format":"int32","readOnly":true},"errorMessage":{"type":"string","readOnly":true},"description":{"type":"string","title":"description of this job"},"stateTimestamps":{"type":"object","additionalProperties":{"type":"string","format":"date-time"},"title":"Timestamps for each state"},"appId":{"type":"string"},"templateInfo":{"$ref":"#/components/schemas/jobJobTemplate"}}},"jobJobConfig":{"type":"object","properties":{"taskTimeout":{"type":"integer","format":"int64","title":"task timeout in seconds"},"jobTimeout":{"type":"integer","format":"int64","title":"job timeout in seconds"},"isTestJob":{"type":"boolean","title":"'true' if this job is a test job"}}},"jobByteLevel":{"type":"string","enum":["EXECUTION_PRIORITY_UNDEFINED","EXECUTION_PRIORITY_CHEAP","EXECUTION_PRIORITY_BALANCED","EXECUTION_PRIORITY_FAST"],"default":"EXECUTION_PRIORITY_UNDEFINED"},"commonSelectionList":{"type":"object","properties":{"blacklist":{"type":"array","items":{"type":"string"}},"whitelist":{"type":"array","items":{"type":"string"}}}},"jobJobState":{"type":"string","enum":["JOB_STATE_NEW","JOB_STATE_STARTED","JOB_STATE_UPLOADING","JOB_STATE_PARTITIONING","JOB_STATE_PARTITIONED","JOB_STATE_TASKS_COMPLETED","JOB_STATE_MERGING","JOB_STATE_MERGED","JOB_STATE_DOWNLOADING","JOB_STATE_COMPLETE","JOB_STATE_FAILED"],"default":"JOB_STATE_NEW","description":" - JOB_STATE_NEW: The job has been created, and the user may still be updating its data sources and parameters.\n - JOB_STATE_STARTED: The job has begun execution after passing validation checks, including data sources, parameters, account balance, and grace period.\n - JOB_STATE_UPLOADING: The job has been retrieved from the partitioner’s job queue and is being sent to the appropriate partitioning engine. Reaching this state confirms the presence of a suitable partitioning engine.\n - JOB_STATE_PARTITIONING: The partitioning engine processes the job and generates multiple chunks, preparing them for further execution.\n - JOB_STATE_PARTITIONED: The partitioning engine has successfully divided the job into chunks, forwarding them to the feeder for distribution. Workers begin fetching and processing these chunks.\n - JOB_STATE_TASKS_COMPLETED: All assigned tasks have been successfully processed by the task runner\n - JOB_STATE_MERGING: The assembler engine retrieves and merges the processed data.\n - JOB_STATE_MERGED: The assembler engine has successfully completed merging the processed chunks. The final result is now prepared for uploading to the specified destination.\n - JOB_STATE_DOWNLOADING: The final output is being saved to the designated data destination.\n - JOB_STATE_COMPLETE: The job lifecycle is successfully completed, and the result has been uploaded to the specified destination.\n - JOB_STATE_FAILED: The job has encountered an error and failed to produce output."},"data_sourceDataSource":{"type":"object","properties":{"dataSourceDescriptor":{"type":"string","description":"Data source selector."},"params":{"$ref":"#/components/schemas/protobufAny","description":"Data source parameters."}},"description":"The data source object specifying configurations for inputs and outputs. Please refer to the dedicated guide for detailed instructions."},"protobufAny":{"type":"object","properties":{"@type":{"type":"string"}},"additionalProperties":{}},"jobAppParams":{"type":"object","properties":{"preset":{"type":"string","description":"[Deprecated] Preset configuration. This field is no longer in use."},"partitioner":{"type":"object","description":"Sets parameters for the partitioning engine."},"assembler":{"type":"object","description":"Sets parameters for the assembling engine."},"app":{"type":"object","description":"Sets parameters for the application.."}}},"jobJobTemplate":{"type":"object","properties":{"id":{"type":"string","title":"Unique ID for this Job Template (primary key)"},"owner":{"type":"string","title":"Owner of this Job Template (primary key)"},"description":{"type":"string","title":"Description of this Job Template"},"app":{"type":"string","title":"The application associated with this Job Template"},"partitioner":{"type":"string","title":"How data is partitioned"},"assembler":{"type":"string","title":"How data is assembled/merged"}}},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}}}},"paths":{"/jobs/{jobId}/configs":{"patch":{"summary":"Set job configs","description":"Set or update execution parameters/configurations","operationId":"Customer_SetJobPreferences","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/jobsJobResponse"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/jobsJobResponse"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"parameters":[{"schema":{"type":"string"},"name":"jobId","description":"The id associated with your job.","in":"path","required":true}],"tags":["Jobs"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/jobJobConfig"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/jobJobConfig"}}},"required":true}}}}}
```


# Manage

***

## Run a job

> Run a job

```json
{"openapi":"3.1.1","info":{"title":"ByteNite jobs API","version":"0.1"},"tags":[],"servers":[{"url":"https://api.bytenite.com/v1/customer"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"commonGenericResponse":{"type":"object","properties":{"ok":{"type":"boolean","description":"True if the request was successful."},"requestId":{"type":"string","description":"Internal request identifier for tracing or support."},"message":{"type":"string","description":"Additional message providing status or context."},"error":{"$ref":"#/components/schemas/commonError","description":"Optional error information if the request failed."}}},"commonError":{"type":"object","properties":{"code":{"type":"integer","format":"int64","description":"Error code if the request failed."},"message":{"type":"string","description":"Short description of the error if occurred."},"description":{"type":"string","description":"Full detailed explanation of the error if applicable."}}},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}},"protobufAny":{"type":"object","properties":{"@type":{"type":"string"}},"additionalProperties":{}},"jobJobConfig":{"type":"object","properties":{"taskTimeout":{"type":"integer","format":"int64","title":"task timeout in seconds"},"jobTimeout":{"type":"integer","format":"int64","title":"job timeout in seconds"},"isTestJob":{"type":"boolean","title":"'true' if this job is a test job"}}}}},"paths":{"/jobs/{jobId}/run":{"post":{"summary":"Run a job","description":"Run a job","operationId":"Customer_RunJob","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/commonGenericResponse"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/commonGenericResponse"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"parameters":[{"schema":{"type":"string"},"name":"jobId","description":"The id associated with your job.","in":"path","required":true}],"tags":["Jobs"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"config":{"$ref":"#/components/schemas/jobJobConfig","description":"Job execution preferences."}}}},"application/x-protobuf":{"schema":{"type":"object","properties":{"config":{"$ref":"#/components/schemas/jobJobConfig","description":"Job execution preferences."}}}}},"required":true}}}}}
```

***

## Stop a running job

> Abort running job (an incomplete job that is yet to start will be deleted)

```json
{"openapi":"3.1.1","info":{"title":"ByteNite jobs API","version":"0.1"},"tags":[],"servers":[{"url":"https://api.bytenite.com/v1/customer"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"commonGenericResponse":{"type":"object","properties":{"ok":{"type":"boolean","description":"True if the request was successful."},"requestId":{"type":"string","description":"Internal request identifier for tracing or support."},"message":{"type":"string","description":"Additional message providing status or context."},"error":{"$ref":"#/components/schemas/commonError","description":"Optional error information if the request failed."}}},"commonError":{"type":"object","properties":{"code":{"type":"integer","format":"int64","description":"Error code if the request failed."},"message":{"type":"string","description":"Short description of the error if occurred."},"description":{"type":"string","description":"Full detailed explanation of the error if applicable."}}},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}},"protobufAny":{"type":"object","properties":{"@type":{"type":"string"}},"additionalProperties":{}}}},"paths":{"/jobs/{jobId}/abort":{"post":{"summary":"Stop a running job","description":"Abort running job (an incomplete job that is yet to start will be deleted)","operationId":"Customer_AbortJob","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/commonGenericResponse"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/commonGenericResponse"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"parameters":[{"schema":{"type":"string"},"name":"jobId","description":"The id associated with your job.","in":"path","required":true}],"tags":["Jobs"]}}}}
```

***

## Delete a job

> Delete a job

```json
{"openapi":"3.1.1","info":{"title":"ByteNite jobs API","version":"0.1"},"tags":[],"servers":[{"url":"https://api.bytenite.com/v1/customer"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"commonGenericResponse":{"type":"object","properties":{"ok":{"type":"boolean","description":"True if the request was successful."},"requestId":{"type":"string","description":"Internal request identifier for tracing or support."},"message":{"type":"string","description":"Additional message providing status or context."},"error":{"$ref":"#/components/schemas/commonError","description":"Optional error information if the request failed."}}},"commonError":{"type":"object","properties":{"code":{"type":"integer","format":"int64","description":"Error code if the request failed."},"message":{"type":"string","description":"Short description of the error if occurred."},"description":{"type":"string","description":"Full detailed explanation of the error if applicable."}}},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}},"protobufAny":{"type":"object","properties":{"@type":{"type":"string"}},"additionalProperties":{}}}},"paths":{"/jobs/{jobId}":{"delete":{"summary":"Delete a job","description":"Delete a job","operationId":"Customer_DeleteJob","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/commonGenericResponse"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/commonGenericResponse"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"parameters":[{"schema":{"type":"string"},"name":"jobId","description":"The id associated with your job.","in":"path","required":true}],"tags":["Jobs"]}}}}
```


# Other

***

## Get the number of running tasks for the jobs

> Get the number of running tasks for the jobs

```json
{"openapi":"3.1.1","info":{"title":"ByteNite jobs API","version":"0.1"},"tags":[],"servers":[{"url":"https://api.bytenite.com/v1/customer"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"customerJobsRunningTasksResponse":{"type":"object","properties":{"jobsRunningTasks":{"type":"object","additionalProperties":{"type":"string","format":"uint64"},"title":"The number of running tasks for the provided jobs"}}},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}},"protobufAny":{"type":"object","properties":{"@type":{"type":"string"}},"additionalProperties":{}},"customerJobsRunningTasksRequest":{"type":"object","properties":{"jobsIds":{"type":"array","items":{"type":"string"},"title":"The id(s) of the job(s) you want to query"}},"description":"Get the running tasks for the provided jobs.","required":["jobsIds"]}}},"paths":{"/jobs/runningTasks":{"post":{"summary":"Get the number of running tasks for the jobs","description":"Get the number of running tasks for the jobs","operationId":"Customer_GetJobsRunningTasks","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/customerJobsRunningTasksResponse"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/customerJobsRunningTasksResponse"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"tags":["Jobs"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/customerJobsRunningTasksRequest"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/customerJobsRunningTasksRequest"}}},"description":"Get the running tasks for the provided jobs.","required":true}}}}}
```

***

## Set upload completed

> Set a job local file upload completed

```json
{"openapi":"3.1.1","info":{"title":"ByteNite jobs API","version":"0.1"},"tags":[],"servers":[{"url":"https://api.bytenite.com/v1/customer"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"commonGenericResponse":{"type":"object","properties":{"ok":{"type":"boolean","description":"True if the request was successful."},"requestId":{"type":"string","description":"Internal request identifier for tracing or support."},"message":{"type":"string","description":"Additional message providing status or context."},"error":{"$ref":"#/components/schemas/commonError","description":"Optional error information if the request failed."}}},"commonError":{"type":"object","properties":{"code":{"type":"integer","format":"int64","description":"Error code if the request failed."},"message":{"type":"string","description":"Short description of the error if occurred."},"description":{"type":"string","description":"Full detailed explanation of the error if applicable."}}},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}},"protobufAny":{"type":"object","properties":{"@type":{"type":"string"}},"additionalProperties":{}}}},"paths":{"/jobs/{jobId}/uploadcompleted":{"patch":{"summary":"Set upload completed","description":"Set a job local file upload completed","operationId":"Customer_SetUploadCompleted","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/commonGenericResponse"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/commonGenericResponse"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"parameters":[{"schema":{"type":"string"},"name":"jobId","description":"The id associated with your job.","in":"path","required":true}],"tags":["Jobs"]}}}}
```

***


# Logs

***

## Get logs

> Get logs for the provided filters

```json
{"openapi":"3.1.1","info":{"title":"ByteNite jobs API","version":"0.1"},"tags":[],"servers":[{"url":"https://api.bytenite.com/v1/customer"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"logsGetLogsResponse":{"type":"object","properties":{"partitioner":{"type":"array","items":{"$ref":"#/components/schemas/logsLogInstance"}},"assembler":{"type":"array","items":{"$ref":"#/components/schemas/logsLogInstance"}},"taskrunner":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/logsLogInstances"}}}},"logsLogInstance":{"type":"object","properties":{"log":{"type":"string","title":"The log message, this is the actual log message received from the loki server"},"timestamp":{"type":"string","format":"date-time","title":"The timestamp of the log message"},"level":{"$ref":"#/components/schemas/logsLogLevel","title":"The log level of the log message"},"container":{"type":"string","title":"Container name from which the log message was generated"}}},"logsLogLevel":{"type":"string","enum":["UNKNOWN","TRACE","DEBUG","INFO","WARN","ERROR","FATAL","PANIC"],"default":"UNKNOWN"},"logsLogInstances":{"type":"object","properties":{"logs":{"type":"array","items":{"$ref":"#/components/schemas/logsLogInstance"}}}},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}},"protobufAny":{"type":"object","properties":{"@type":{"type":"string"}},"additionalProperties":{}},"logsGetLogsRequest":{"type":"object","properties":{"jobId":{"type":"string","title":"The job id for which you want to get the logs"},"taskIds":{"type":"array","items":{"type":"string"},"title":"The task ids for which you want to get the logs"},"levels":{"type":"array","items":{"$ref":"#/components/schemas/logsLogLevel"},"title":"The log levels you want to get the logs for"},"services":{"type":"array","items":{"$ref":"#/components/schemas/logsLogService"},"title":"The services you want to get the logs for"}},"required":["jobId"]},"logsLogService":{"type":"string","enum":["PARTITIONER","ASSEMBLER","TASKRUNNER"],"default":"PARTITIONER"}}},"paths":{"/logs":{"post":{"summary":"Get logs","description":"Get logs for the provided filters","operationId":"Customer_GetLogs","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/logsGetLogsResponse"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/logsGetLogsResponse"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"tags":["Logs"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/logsGetLogsRequest"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/logsGetLogsRequest"}}},"required":true}}}}}
```


# Data Sources

***

## Test a data source

> Test and get information about a data source connection

```json
{"openapi":"3.1.1","info":{"title":"ByteNite jobs API","version":"0.1"},"tags":[],"servers":[{"url":"https://api.bytenite.com/v1/customer"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"jobsDataSourceInfoResponse":{"type":"object","properties":{"filename":{"type":"string"},"path":{"type":"string"},"size":{"type":"string","format":"uint64"},"properties":{"type":"object","additionalProperties":{"type":"string"}},"tempUrl":{"type":"string"},"files":{"$ref":"#/components/schemas/jobsDirectory"}}},"jobsDirectory":{"type":"object","properties":{"name":{"type":"string"},"path":{"type":"string"},"directories":{"type":"array","items":{"$ref":"#/components/schemas/jobsDirectory"}},"files":{"type":"array","items":{"$ref":"#/components/schemas/jobsFile"}}}},"jobsFile":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"path":{"type":"string"},"size":{"type":"string","format":"uint64"}}},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}},"protobufAny":{"type":"object","properties":{"@type":{"type":"string"}},"additionalProperties":{}},"jobsDataSourceInfoRequest":{"type":"object","properties":{"dataSource":{"$ref":"#/components/schemas/data_sourceDataSource"},"listFiles":{"type":"boolean"}}},"data_sourceDataSource":{"type":"object","properties":{"dataSourceDescriptor":{"type":"string","description":"Data source selector."},"params":{"$ref":"#/components/schemas/protobufAny","description":"Data source parameters."}},"description":"The data source object specifying configurations for inputs and outputs. Please refer to the dedicated guide for detailed instructions."}}},"paths":{"/datasource/test":{"post":{"summary":"Test a data source","description":"Test and get information about a data source connection","operationId":"Customer_DataSourceInfo","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/jobsDataSourceInfoResponse"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/jobsDataSourceInfoResponse"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"tags":["Jobs"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/jobsDataSourceInfoRequest"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/jobsDataSourceInfoRequest"}}},"required":true}}}}}
```


# Templates

***

## Get available job templates

> Get available job templates

```json
{"openapi":"3.1.1","info":{"title":"ByteNite jobs API","version":"0.1"},"tags":[],"servers":[{"url":"https://api.bytenite.com/v1/customer"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"jobsJobTemplatesResponse":{"type":"object","properties":{"pagination":{"$ref":"#/components/schemas/commonPaginatedResponse"},"data":{"type":"array","items":{"$ref":"#/components/schemas/jobJobTemplate"}}}},"commonPaginatedResponse":{"type":"object","properties":{"total":{"type":"integer","format":"int64","description":"The total number of transactions available."},"offset":{"type":"integer","format":"int64","description":"The starting position of the current page of results, starting from 0."},"hasPrevious":{"type":"boolean","description":"A boolean value (True/False) indicating whether there's a previous page of results. False if the current page is the first page."},"hasNext":{"type":"boolean","description":"A boolean value indicating whether there's a next page of results."}},"description":"This section provides information about how the results are divided into pages."},"jobJobTemplate":{"type":"object","properties":{"id":{"type":"string","title":"Unique ID for this Job Template (primary key)"},"owner":{"type":"string","title":"Owner of this Job Template (primary key)"},"description":{"type":"string","title":"Description of this Job Template"},"app":{"type":"string","title":"The application associated with this Job Template"},"partitioner":{"type":"string","title":"How data is partitioned"},"assembler":{"type":"string","title":"How data is assembled/merged"}}},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}},"protobufAny":{"type":"object","properties":{"@type":{"type":"string"}},"additionalProperties":{}}}},"paths":{"/jobs/templates":{"get":{"summary":"Get available job templates","description":"Get available job templates","operationId":"Customer_GetJobTemplates","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/jobsJobTemplatesResponse"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/jobsJobTemplatesResponse"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"parameters":[{"schema":{"type":"integer","format":"int64"},"name":"pagination.limit","description":"Number of rows to return per page.","in":"query","required":false},{"schema":{"type":"integer","format":"int64"},"name":"pagination.offset","description":"Number of rows to skip before starting to collect the result set.","in":"query","required":false},{"schema":{"type":"string"},"name":"orderBy","description":"Field to order the results by. Defaults to 'created_at'.","in":"query","required":false}],"tags":["Jobs"]}}}}
```


# Events

***

## Listen events

> Listen events

```json
{"openapi":"3.1.1","info":{"title":"ByteNite jobs API","version":"0.1"},"tags":[],"servers":[{"url":"https://api.bytenite.com/v1/customer"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"bytenitecustomerEvent":{"type":"object","properties":{"event":{"type":"string"},"data":{"$ref":"#/components/schemas/protobufAny"}}},"protobufAny":{"type":"object","properties":{"@type":{"type":"string"}},"additionalProperties":{}},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}}}},"paths":{"/events":{"get":{"summary":"Listen events","description":"Listen events","operationId":"Customer_Events","responses":{"200":{"description":"A successful response.(streaming responses)","content":{"application/json":{"schema":{"type":"object","properties":{"result":{"$ref":"#/components/schemas/bytenitecustomerEvent"},"error":{"$ref":"#/components/schemas/rpcStatus"}},"title":"Stream result of bytenitecustomerEvent"}},"application/x-protobuf":{"schema":{"type":"object","properties":{"result":{"$ref":"#/components/schemas/bytenitecustomerEvent"},"error":{"$ref":"#/components/schemas/rpcStatus"}},"title":"Stream result of bytenitecustomerEvent"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"tags":["Events"]}}}}
```


# Authentication API

## About

* Base URL: `https://api.bytenite.com/v1/auth`
* Version: `v1`
* Swagger Docs: <https://api.bytenite.com/v1/auth/docs/>
* Specification: <https://api.bytenite.com/v1/auth/docs/swagger.json>

## Notes

ByteNite uses **OAuth2** for authentication and authorization. OAuth2 is a widely-used open standard that allows applications to securely access resources on behalf of a user without exposing their credentials.

***

## Retrieve information about server

> Server software version

```json
{"openapi":"3.1.1","info":{"title":"ByteNite auth API","version":"0.1"},"tags":[],"servers":[{"url":"https://api.bytenite.com/v1/auth"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"authServerInfoResponse":{"type":"object","properties":{"version":{"$ref":"#/components/schemas/commonVersion"}},"title":"Responses"},"commonVersion":{"type":"object","properties":{"major":{"type":"integer","format":"int64"},"minor":{"type":"integer","format":"int64"},"tag":{"type":"string"}},"description":"A semantic version for managing updates."},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}},"protobufAny":{"type":"object","properties":{"@type":{"type":"string","description":"A URL/resource name that uniquely identifies the type of the serialized\nprotocol buffer message. This string must contain at least\none \"/\" character. The last segment of the URL's path must represent\nthe fully qualified name of the type (as in\n'path/google.protobuf.Duration'). The name should be in a canonical form\n(e.g., leading \".\" is not accepted).\n\nIn practice, teams usually precompile into the binary all types that they\nexpect it to use in the context of Any. However, for URLs which use the\nscheme 'http', 'https', or no scheme, one can optionally set up a type\nserver that maps type URLs to message definitions as follows:\n\n* If no scheme is provided, 'https' is assumed.\n* An HTTP GET on the URL must yield a [google.protobuf.Type][]\n  value in binary format, or produce an error.\n* Applications are allowed to cache lookup results based on the\n  URL, or have them precompiled into a binary to avoid any\n  lookup. Therefore, binary compatibility needs to be preserved\n  on changes to types. (Use versioned type names to manage\n  breaking changes.)\n\nNote: this functionality is not currently available in the official\nprotobuf release, and it is not used for type URLs beginning with\ntype.googleapis.com.\n\nSchemes other than 'http', 'https' (or the empty scheme) might be\nused with implementation specific semantics."}},"additionalProperties":{},"description":"'Any' contains an arbitrary serialized protocol buffer message along with a\nURL that describes the type of the serialized message.\n\nProtobuf library provides support to pack/unpack Any values in the form\nof utility functions or additional generated methods of the Any type.\n\nExample 1: Pack and unpack a message in C++.\n\n    Foo foo = ...;\n    Any any;\n    any.PackFrom(foo);\n    ...\n    if (any.UnpackTo(&foo)) {\n      ...\n    }\n\nExample 2: Pack and unpack a message in Java.\n\n    Foo foo = ...;\n    Any any = Any.pack(foo);\n    ...\n    if (any.is(Foo.class)) {\n      foo = any.unpack(Foo.class);\n    }\n\n Example 3: Pack and unpack a message in Python.\n\n    foo = Foo(...)\n    any = Any()\n    any.Pack(foo)\n    ...\n    if any.Is(Foo.DESCRIPTOR):\n      any.Unpack(foo)\n      ...\n\n Example 4: Pack and unpack a message in Go\n\n     foo := &pb.Foo{...}\n     any, err := anypb.New(foo)\n     if err != nil {\n       ...\n     }\n     ...\n     foo := &pb.Foo{}\n     if err := any.UnmarshalTo(foo); err != nil {\n       ...\n     }\n\nThe pack methods provided by protobuf library will by default use\n'type.googleapis.com/full.type.name' as the type URL and the unpack\nmethods only use the fully qualified type name after the last '/'\nin the type URL, for example \"foo.bar.com/x/y.z\" will yield type\nname \"y.z\".\n\n\nJSON\n====\nThe JSON representation of an 'Any' value uses the regular\nrepresentation of the deserialized, embedded message, with an\nadditional field '@type' which contains the type URL. Example:\n\n    package google.profile;\n    message Person {\n      string first_name = 1;\n      string last_name = 2;\n    }\n\n    {\n      \"@type\": \"type.googleapis.com/google.profile.Person\",\n      \"firstName\": <string>,\n      \"lastName\": <string>\n    }\n\nIf the embedded message type is well-known and has a custom JSON\nrepresentation, that representation will be embedded adding a field\n'value' which holds the custom JSON in addition to the '@type'\nfield. Example (for message [google.protobuf.Duration][]):\n\n    {\n      \"@type\": \"type.googleapis.com/google.protobuf.Duration\",\n      \"value\": \"1.212s\"\n    }"}}},"paths":{"/info":{"get":{"summary":"Retrieve information about server","description":"Server software version","operationId":"Auth_Info","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/authServerInfoResponse"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/authServerInfoResponse"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"tags":["info"]}}}}
```


# Access Token

In order to authorize your API calls, you will need an access token. For security, the only way to programmatically obtain an access token is by exchanging it for an API key. Learn how to:

* [Onboarding](/getting-started/onboarding#get-an-api-key)
* [Exchange API key for access token](#access_token)

***

## Exchange API key for access token

> Exchange an API key for an oAuth2 access token

```json
{"openapi":"3.1.1","info":{"title":"ByteNite auth API","version":"0.1"},"tags":[],"servers":[{"url":"https://api.bytenite.com/v1/auth"}],"security":[],"paths":{"/access_token":{"post":{"summary":"Exchange API key for access token","description":"Exchange an API key for an oAuth2 access token","operationId":"Auth_RequestAccessToken","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/authAccessTokenResponse"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/authAccessTokenResponse"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"tags":["auth"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/authAccessTokenRequest"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/authAccessTokenRequest"}}},"required":true}}}},"components":{"schemas":{"authAccessTokenResponse":{"type":"object","properties":{"token":{"type":"string","title":"JWT Access token that you can use to authenticate secured API endpoints"},"expiresIn":{"type":"string","format":"int64","title":"Duration in seconds until the token expires"},"scope":{"type":"string"}}},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}},"protobufAny":{"type":"object","properties":{"@type":{"type":"string","description":"A URL/resource name that uniquely identifies the type of the serialized\nprotocol buffer message. This string must contain at least\none \"/\" character. The last segment of the URL's path must represent\nthe fully qualified name of the type (as in\n'path/google.protobuf.Duration'). The name should be in a canonical form\n(e.g., leading \".\" is not accepted).\n\nIn practice, teams usually precompile into the binary all types that they\nexpect it to use in the context of Any. However, for URLs which use the\nscheme 'http', 'https', or no scheme, one can optionally set up a type\nserver that maps type URLs to message definitions as follows:\n\n* If no scheme is provided, 'https' is assumed.\n* An HTTP GET on the URL must yield a [google.protobuf.Type][]\n  value in binary format, or produce an error.\n* Applications are allowed to cache lookup results based on the\n  URL, or have them precompiled into a binary to avoid any\n  lookup. Therefore, binary compatibility needs to be preserved\n  on changes to types. (Use versioned type names to manage\n  breaking changes.)\n\nNote: this functionality is not currently available in the official\nprotobuf release, and it is not used for type URLs beginning with\ntype.googleapis.com.\n\nSchemes other than 'http', 'https' (or the empty scheme) might be\nused with implementation specific semantics."}},"additionalProperties":{},"description":"'Any' contains an arbitrary serialized protocol buffer message along with a\nURL that describes the type of the serialized message.\n\nProtobuf library provides support to pack/unpack Any values in the form\nof utility functions or additional generated methods of the Any type.\n\nExample 1: Pack and unpack a message in C++.\n\n    Foo foo = ...;\n    Any any;\n    any.PackFrom(foo);\n    ...\n    if (any.UnpackTo(&foo)) {\n      ...\n    }\n\nExample 2: Pack and unpack a message in Java.\n\n    Foo foo = ...;\n    Any any = Any.pack(foo);\n    ...\n    if (any.is(Foo.class)) {\n      foo = any.unpack(Foo.class);\n    }\n\n Example 3: Pack and unpack a message in Python.\n\n    foo = Foo(...)\n    any = Any()\n    any.Pack(foo)\n    ...\n    if any.Is(Foo.DESCRIPTOR):\n      any.Unpack(foo)\n      ...\n\n Example 4: Pack and unpack a message in Go\n\n     foo := &pb.Foo{...}\n     any, err := anypb.New(foo)\n     if err != nil {\n       ...\n     }\n     ...\n     foo := &pb.Foo{}\n     if err := any.UnmarshalTo(foo); err != nil {\n       ...\n     }\n\nThe pack methods provided by protobuf library will by default use\n'type.googleapis.com/full.type.name' as the type URL and the unpack\nmethods only use the fully qualified type name after the last '/'\nin the type URL, for example \"foo.bar.com/x/y.z\" will yield type\nname \"y.z\".\n\n\nJSON\n====\nThe JSON representation of an 'Any' value uses the regular\nrepresentation of the deserialized, embedded message, with an\nadditional field '@type' which contains the type URL. Example:\n\n    package google.profile;\n    message Person {\n      string first_name = 1;\n      string last_name = 2;\n    }\n\n    {\n      \"@type\": \"type.googleapis.com/google.profile.Person\",\n      \"firstName\": <string>,\n      \"lastName\": <string>\n    }\n\nIf the embedded message type is well-known and has a custom JSON\nrepresentation, that representation will be embedded adding a field\n'value' which holds the custom JSON in addition to the '@type'\nfield. Example (for message [google.protobuf.Duration][]):\n\n    {\n      \"@type\": \"type.googleapis.com/google.protobuf.Duration\",\n      \"value\": \"1.212s\"\n    }"},"authAccessTokenRequest":{"type":"object","properties":{"apiKey":{"type":"string","description":"The actual API key that you have received from the API key request."}},"required":["apiKey"]}}}}
```

***

## User signout

> Log out current user and invalidates token

```json
{"openapi":"3.1.1","info":{"title":"ByteNite auth API","version":"0.1"},"tags":[],"servers":[{"url":"https://api.bytenite.com/v1/auth"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"commonGenericResponse":{"type":"object","properties":{"ok":{"type":"boolean","description":"True if the request was successful."},"requestId":{"type":"string","description":"Internal request identifier for tracing or support."},"message":{"type":"string","description":"Additional message providing status or context."},"error":{"$ref":"#/components/schemas/commonError","description":"Optional error information if the request failed."}}},"commonError":{"type":"object","properties":{"code":{"type":"integer","format":"int64","description":"Error code if the request failed."},"message":{"type":"string","description":"Short description of the error if occurred."},"description":{"type":"string","description":"Full detailed explanation of the error if applicable."}}},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}},"protobufAny":{"type":"object","properties":{"@type":{"type":"string","description":"A URL/resource name that uniquely identifies the type of the serialized\nprotocol buffer message. This string must contain at least\none \"/\" character. The last segment of the URL's path must represent\nthe fully qualified name of the type (as in\n'path/google.protobuf.Duration'). The name should be in a canonical form\n(e.g., leading \".\" is not accepted).\n\nIn practice, teams usually precompile into the binary all types that they\nexpect it to use in the context of Any. However, for URLs which use the\nscheme 'http', 'https', or no scheme, one can optionally set up a type\nserver that maps type URLs to message definitions as follows:\n\n* If no scheme is provided, 'https' is assumed.\n* An HTTP GET on the URL must yield a [google.protobuf.Type][]\n  value in binary format, or produce an error.\n* Applications are allowed to cache lookup results based on the\n  URL, or have them precompiled into a binary to avoid any\n  lookup. Therefore, binary compatibility needs to be preserved\n  on changes to types. (Use versioned type names to manage\n  breaking changes.)\n\nNote: this functionality is not currently available in the official\nprotobuf release, and it is not used for type URLs beginning with\ntype.googleapis.com.\n\nSchemes other than 'http', 'https' (or the empty scheme) might be\nused with implementation specific semantics."}},"additionalProperties":{},"description":"'Any' contains an arbitrary serialized protocol buffer message along with a\nURL that describes the type of the serialized message.\n\nProtobuf library provides support to pack/unpack Any values in the form\nof utility functions or additional generated methods of the Any type.\n\nExample 1: Pack and unpack a message in C++.\n\n    Foo foo = ...;\n    Any any;\n    any.PackFrom(foo);\n    ...\n    if (any.UnpackTo(&foo)) {\n      ...\n    }\n\nExample 2: Pack and unpack a message in Java.\n\n    Foo foo = ...;\n    Any any = Any.pack(foo);\n    ...\n    if (any.is(Foo.class)) {\n      foo = any.unpack(Foo.class);\n    }\n\n Example 3: Pack and unpack a message in Python.\n\n    foo = Foo(...)\n    any = Any()\n    any.Pack(foo)\n    ...\n    if any.Is(Foo.DESCRIPTOR):\n      any.Unpack(foo)\n      ...\n\n Example 4: Pack and unpack a message in Go\n\n     foo := &pb.Foo{...}\n     any, err := anypb.New(foo)\n     if err != nil {\n       ...\n     }\n     ...\n     foo := &pb.Foo{}\n     if err := any.UnmarshalTo(foo); err != nil {\n       ...\n     }\n\nThe pack methods provided by protobuf library will by default use\n'type.googleapis.com/full.type.name' as the type URL and the unpack\nmethods only use the fully qualified type name after the last '/'\nin the type URL, for example \"foo.bar.com/x/y.z\" will yield type\nname \"y.z\".\n\n\nJSON\n====\nThe JSON representation of an 'Any' value uses the regular\nrepresentation of the deserialized, embedded message, with an\nadditional field '@type' which contains the type URL. Example:\n\n    package google.profile;\n    message Person {\n      string first_name = 1;\n      string last_name = 2;\n    }\n\n    {\n      \"@type\": \"type.googleapis.com/google.profile.Person\",\n      \"firstName\": <string>,\n      \"lastName\": <string>\n    }\n\nIf the embedded message type is well-known and has a custom JSON\nrepresentation, that representation will be embedded adding a field\n'value' which holds the custom JSON in addition to the '@type'\nfield. Example (for message [google.protobuf.Duration][]):\n\n    {\n      \"@type\": \"type.googleapis.com/google.protobuf.Duration\",\n      \"value\": \"1.212s\"\n    }"},"commonEmptyMessage":{"type":"object"}}},"paths":{"/signout":{"post":{"summary":"User signout","description":"Log out current user and invalidates token","operationId":"Auth_SignOut","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/commonGenericResponse"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/commonGenericResponse"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"tags":["auth"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/commonEmptyMessage"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/commonEmptyMessage"}}},"required":true}}}}}
```

***

## Check if the user is already logged in

> Check if the user is already logged in, if the user can skip login a redirect url is returned

```json
{"openapi":"3.1.1","info":{"title":"ByteNite auth API","version":"0.1"},"tags":[],"servers":[{"url":"https://api.bytenite.com/v1/auth"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"authLoginChallengeResponse":{"type":"object","properties":{"skip":{"type":"boolean"},"redirectTo":{"type":"string"}}},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}},"protobufAny":{"type":"object","properties":{"@type":{"type":"string","description":"A URL/resource name that uniquely identifies the type of the serialized\nprotocol buffer message. This string must contain at least\none \"/\" character. The last segment of the URL's path must represent\nthe fully qualified name of the type (as in\n'path/google.protobuf.Duration'). The name should be in a canonical form\n(e.g., leading \".\" is not accepted).\n\nIn practice, teams usually precompile into the binary all types that they\nexpect it to use in the context of Any. However, for URLs which use the\nscheme 'http', 'https', or no scheme, one can optionally set up a type\nserver that maps type URLs to message definitions as follows:\n\n* If no scheme is provided, 'https' is assumed.\n* An HTTP GET on the URL must yield a [google.protobuf.Type][]\n  value in binary format, or produce an error.\n* Applications are allowed to cache lookup results based on the\n  URL, or have them precompiled into a binary to avoid any\n  lookup. Therefore, binary compatibility needs to be preserved\n  on changes to types. (Use versioned type names to manage\n  breaking changes.)\n\nNote: this functionality is not currently available in the official\nprotobuf release, and it is not used for type URLs beginning with\ntype.googleapis.com.\n\nSchemes other than 'http', 'https' (or the empty scheme) might be\nused with implementation specific semantics."}},"additionalProperties":{},"description":"'Any' contains an arbitrary serialized protocol buffer message along with a\nURL that describes the type of the serialized message.\n\nProtobuf library provides support to pack/unpack Any values in the form\nof utility functions or additional generated methods of the Any type.\n\nExample 1: Pack and unpack a message in C++.\n\n    Foo foo = ...;\n    Any any;\n    any.PackFrom(foo);\n    ...\n    if (any.UnpackTo(&foo)) {\n      ...\n    }\n\nExample 2: Pack and unpack a message in Java.\n\n    Foo foo = ...;\n    Any any = Any.pack(foo);\n    ...\n    if (any.is(Foo.class)) {\n      foo = any.unpack(Foo.class);\n    }\n\n Example 3: Pack and unpack a message in Python.\n\n    foo = Foo(...)\n    any = Any()\n    any.Pack(foo)\n    ...\n    if any.Is(Foo.DESCRIPTOR):\n      any.Unpack(foo)\n      ...\n\n Example 4: Pack and unpack a message in Go\n\n     foo := &pb.Foo{...}\n     any, err := anypb.New(foo)\n     if err != nil {\n       ...\n     }\n     ...\n     foo := &pb.Foo{}\n     if err := any.UnmarshalTo(foo); err != nil {\n       ...\n     }\n\nThe pack methods provided by protobuf library will by default use\n'type.googleapis.com/full.type.name' as the type URL and the unpack\nmethods only use the fully qualified type name after the last '/'\nin the type URL, for example \"foo.bar.com/x/y.z\" will yield type\nname \"y.z\".\n\n\nJSON\n====\nThe JSON representation of an 'Any' value uses the regular\nrepresentation of the deserialized, embedded message, with an\nadditional field '@type' which contains the type URL. Example:\n\n    package google.profile;\n    message Person {\n      string first_name = 1;\n      string last_name = 2;\n    }\n\n    {\n      \"@type\": \"type.googleapis.com/google.profile.Person\",\n      \"firstName\": <string>,\n      \"lastName\": <string>\n    }\n\nIf the embedded message type is well-known and has a custom JSON\nrepresentation, that representation will be embedded adding a field\n'value' which holds the custom JSON in addition to the '@type'\nfield. Example (for message [google.protobuf.Duration][]):\n\n    {\n      \"@type\": \"type.googleapis.com/google.protobuf.Duration\",\n      \"value\": \"1.212s\"\n    }"}}},"paths":{"/skip":{"get":{"summary":"Check if the user is already logged in","description":"Check if the user is already logged in, if the user can skip login a redirect url is returned","operationId":"Auth_SkipLogin","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/authLoginChallengeResponse"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/authLoginChallengeResponse"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"parameters":[{"schema":{"type":"string"},"name":"loginChallenge","in":"query","required":false}],"tags":["auth"]}}}}
```


# API Keys

Learn how to create API keys:

* [Onboarding](/getting-started/onboarding#get-an-api-key)

***

## Generic information about user

> Get all issued api keys for user

```json
{"openapi":"3.1.1","info":{"title":"ByteNite auth API","version":"0.1"},"tags":[],"servers":[{"url":"https://api.bytenite.com/v1/auth"}],"security":[{"BearerAuth":["read"]}],"components":{"securitySchemes":{"BearerAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"authApiKeysResponse":{"type":"object","properties":{"apiKeys":{"type":"array","items":{"$ref":"#/components/schemas/authApiKey"}}}},"authApiKey":{"type":"object","properties":{"id":{"type":"string","title":"API key ID"},"name":{"type":"string","title":"API key name, used to identify the key"},"issuedAt":{"type":"string","format":"date-time","title":"Date when the API key was created"},"expiresAt":{"type":"string","format":"date-time","title":"Date when the API key expires"},"userId":{"type":"string","title":"User ID that the API key belongs to"},"revoked":{"type":"boolean","title":"Whether the API key is revoked"},"fingerprint":{"type":"string","title":"The fingerprint of the device that the API key was issued for"}},"description":"Each ByteNite customer can generate multiple API keys with a set expiry for their use. This table details these API keys."},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}},"protobufAny":{"type":"object","properties":{"@type":{"type":"string","description":"A URL/resource name that uniquely identifies the type of the serialized\nprotocol buffer message. This string must contain at least\none \"/\" character. The last segment of the URL's path must represent\nthe fully qualified name of the type (as in\n'path/google.protobuf.Duration'). The name should be in a canonical form\n(e.g., leading \".\" is not accepted).\n\nIn practice, teams usually precompile into the binary all types that they\nexpect it to use in the context of Any. However, for URLs which use the\nscheme 'http', 'https', or no scheme, one can optionally set up a type\nserver that maps type URLs to message definitions as follows:\n\n* If no scheme is provided, 'https' is assumed.\n* An HTTP GET on the URL must yield a [google.protobuf.Type][]\n  value in binary format, or produce an error.\n* Applications are allowed to cache lookup results based on the\n  URL, or have them precompiled into a binary to avoid any\n  lookup. Therefore, binary compatibility needs to be preserved\n  on changes to types. (Use versioned type names to manage\n  breaking changes.)\n\nNote: this functionality is not currently available in the official\nprotobuf release, and it is not used for type URLs beginning with\ntype.googleapis.com.\n\nSchemes other than 'http', 'https' (or the empty scheme) might be\nused with implementation specific semantics."}},"additionalProperties":{},"description":"'Any' contains an arbitrary serialized protocol buffer message along with a\nURL that describes the type of the serialized message.\n\nProtobuf library provides support to pack/unpack Any values in the form\nof utility functions or additional generated methods of the Any type.\n\nExample 1: Pack and unpack a message in C++.\n\n    Foo foo = ...;\n    Any any;\n    any.PackFrom(foo);\n    ...\n    if (any.UnpackTo(&foo)) {\n      ...\n    }\n\nExample 2: Pack and unpack a message in Java.\n\n    Foo foo = ...;\n    Any any = Any.pack(foo);\n    ...\n    if (any.is(Foo.class)) {\n      foo = any.unpack(Foo.class);\n    }\n\n Example 3: Pack and unpack a message in Python.\n\n    foo = Foo(...)\n    any = Any()\n    any.Pack(foo)\n    ...\n    if any.Is(Foo.DESCRIPTOR):\n      any.Unpack(foo)\n      ...\n\n Example 4: Pack and unpack a message in Go\n\n     foo := &pb.Foo{...}\n     any, err := anypb.New(foo)\n     if err != nil {\n       ...\n     }\n     ...\n     foo := &pb.Foo{}\n     if err := any.UnmarshalTo(foo); err != nil {\n       ...\n     }\n\nThe pack methods provided by protobuf library will by default use\n'type.googleapis.com/full.type.name' as the type URL and the unpack\nmethods only use the fully qualified type name after the last '/'\nin the type URL, for example \"foo.bar.com/x/y.z\" will yield type\nname \"y.z\".\n\n\nJSON\n====\nThe JSON representation of an 'Any' value uses the regular\nrepresentation of the deserialized, embedded message, with an\nadditional field '@type' which contains the type URL. Example:\n\n    package google.profile;\n    message Person {\n      string first_name = 1;\n      string last_name = 2;\n    }\n\n    {\n      \"@type\": \"type.googleapis.com/google.profile.Person\",\n      \"firstName\": <string>,\n      \"lastName\": <string>\n    }\n\nIf the embedded message type is well-known and has a custom JSON\nrepresentation, that representation will be embedded adding a field\n'value' which holds the custom JSON in addition to the '@type'\nfield. Example (for message [google.protobuf.Duration][]):\n\n    {\n      \"@type\": \"type.googleapis.com/google.protobuf.Duration\",\n      \"value\": \"1.212s\"\n    }"}}},"paths":{"/api_keys":{"get":{"summary":"Generic information about user","description":"Get all issued api keys for user","operationId":"Auth_ApiKeys","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/authApiKeysResponse"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/authApiKeysResponse"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"tags":["api_keys"]}}}}
```

***

## Revoke an API key

> Revoke an API key

```json
{"openapi":"3.1.1","info":{"title":"ByteNite auth API","version":"0.1"},"tags":[],"servers":[{"url":"https://api.bytenite.com/v1/auth"}],"security":[{"BearerAuth":["read","write"]}],"components":{"securitySchemes":{"BearerAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"commonGenericResponse":{"type":"object","properties":{"ok":{"type":"boolean","description":"True if the request was successful."},"requestId":{"type":"string","description":"Internal request identifier for tracing or support."},"message":{"type":"string","description":"Additional message providing status or context."},"error":{"$ref":"#/components/schemas/commonError","description":"Optional error information if the request failed."}}},"commonError":{"type":"object","properties":{"code":{"type":"integer","format":"int64","description":"Error code if the request failed."},"message":{"type":"string","description":"Short description of the error if occurred."},"description":{"type":"string","description":"Full detailed explanation of the error if applicable."}}},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}},"protobufAny":{"type":"object","properties":{"@type":{"type":"string","description":"A URL/resource name that uniquely identifies the type of the serialized\nprotocol buffer message. This string must contain at least\none \"/\" character. The last segment of the URL's path must represent\nthe fully qualified name of the type (as in\n'path/google.protobuf.Duration'). The name should be in a canonical form\n(e.g., leading \".\" is not accepted).\n\nIn practice, teams usually precompile into the binary all types that they\nexpect it to use in the context of Any. However, for URLs which use the\nscheme 'http', 'https', or no scheme, one can optionally set up a type\nserver that maps type URLs to message definitions as follows:\n\n* If no scheme is provided, 'https' is assumed.\n* An HTTP GET on the URL must yield a [google.protobuf.Type][]\n  value in binary format, or produce an error.\n* Applications are allowed to cache lookup results based on the\n  URL, or have them precompiled into a binary to avoid any\n  lookup. Therefore, binary compatibility needs to be preserved\n  on changes to types. (Use versioned type names to manage\n  breaking changes.)\n\nNote: this functionality is not currently available in the official\nprotobuf release, and it is not used for type URLs beginning with\ntype.googleapis.com.\n\nSchemes other than 'http', 'https' (or the empty scheme) might be\nused with implementation specific semantics."}},"additionalProperties":{},"description":"'Any' contains an arbitrary serialized protocol buffer message along with a\nURL that describes the type of the serialized message.\n\nProtobuf library provides support to pack/unpack Any values in the form\nof utility functions or additional generated methods of the Any type.\n\nExample 1: Pack and unpack a message in C++.\n\n    Foo foo = ...;\n    Any any;\n    any.PackFrom(foo);\n    ...\n    if (any.UnpackTo(&foo)) {\n      ...\n    }\n\nExample 2: Pack and unpack a message in Java.\n\n    Foo foo = ...;\n    Any any = Any.pack(foo);\n    ...\n    if (any.is(Foo.class)) {\n      foo = any.unpack(Foo.class);\n    }\n\n Example 3: Pack and unpack a message in Python.\n\n    foo = Foo(...)\n    any = Any()\n    any.Pack(foo)\n    ...\n    if any.Is(Foo.DESCRIPTOR):\n      any.Unpack(foo)\n      ...\n\n Example 4: Pack and unpack a message in Go\n\n     foo := &pb.Foo{...}\n     any, err := anypb.New(foo)\n     if err != nil {\n       ...\n     }\n     ...\n     foo := &pb.Foo{}\n     if err := any.UnmarshalTo(foo); err != nil {\n       ...\n     }\n\nThe pack methods provided by protobuf library will by default use\n'type.googleapis.com/full.type.name' as the type URL and the unpack\nmethods only use the fully qualified type name after the last '/'\nin the type URL, for example \"foo.bar.com/x/y.z\" will yield type\nname \"y.z\".\n\n\nJSON\n====\nThe JSON representation of an 'Any' value uses the regular\nrepresentation of the deserialized, embedded message, with an\nadditional field '@type' which contains the type URL. Example:\n\n    package google.profile;\n    message Person {\n      string first_name = 1;\n      string last_name = 2;\n    }\n\n    {\n      \"@type\": \"type.googleapis.com/google.profile.Person\",\n      \"firstName\": <string>,\n      \"lastName\": <string>\n    }\n\nIf the embedded message type is well-known and has a custom JSON\nrepresentation, that representation will be embedded adding a field\n'value' which holds the custom JSON in addition to the '@type'\nfield. Example (for message [google.protobuf.Duration][]):\n\n    {\n      \"@type\": \"type.googleapis.com/google.protobuf.Duration\",\n      \"value\": \"1.212s\"\n    }"}}},"paths":{"/api_keys/{id}/revoke":{"post":{"summary":"Revoke an API key","description":"Revoke an API key","operationId":"Auth_RevokeApiKey","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/commonGenericResponse"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/commonGenericResponse"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"parameters":[{"schema":{"type":"string"},"name":"id","in":"path","required":true}],"tags":["api_keys"]}}}}
```


# Secrets

***

## Create or update a secret

> Save a secret for data sources/destinations usage

```json
{"openapi":"3.1.1","info":{"title":"ByteNite auth API","version":"0.1"},"tags":[],"servers":[{"url":"https://api.bytenite.com/v1/auth"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"commonGenericResponse":{"type":"object","properties":{"ok":{"type":"boolean","description":"True if the request was successful."},"requestId":{"type":"string","description":"Internal request identifier for tracing or support."},"message":{"type":"string","description":"Additional message providing status or context."},"error":{"$ref":"#/components/schemas/commonError","description":"Optional error information if the request failed."}}},"commonError":{"type":"object","properties":{"code":{"type":"integer","format":"int64","description":"Error code if the request failed."},"message":{"type":"string","description":"Short description of the error if occurred."},"description":{"type":"string","description":"Full detailed explanation of the error if applicable."}}},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}},"protobufAny":{"type":"object","properties":{"@type":{"type":"string","description":"A URL/resource name that uniquely identifies the type of the serialized\nprotocol buffer message. This string must contain at least\none \"/\" character. The last segment of the URL's path must represent\nthe fully qualified name of the type (as in\n'path/google.protobuf.Duration'). The name should be in a canonical form\n(e.g., leading \".\" is not accepted).\n\nIn practice, teams usually precompile into the binary all types that they\nexpect it to use in the context of Any. However, for URLs which use the\nscheme 'http', 'https', or no scheme, one can optionally set up a type\nserver that maps type URLs to message definitions as follows:\n\n* If no scheme is provided, 'https' is assumed.\n* An HTTP GET on the URL must yield a [google.protobuf.Type][]\n  value in binary format, or produce an error.\n* Applications are allowed to cache lookup results based on the\n  URL, or have them precompiled into a binary to avoid any\n  lookup. Therefore, binary compatibility needs to be preserved\n  on changes to types. (Use versioned type names to manage\n  breaking changes.)\n\nNote: this functionality is not currently available in the official\nprotobuf release, and it is not used for type URLs beginning with\ntype.googleapis.com.\n\nSchemes other than 'http', 'https' (or the empty scheme) might be\nused with implementation specific semantics."}},"additionalProperties":{},"description":"'Any' contains an arbitrary serialized protocol buffer message along with a\nURL that describes the type of the serialized message.\n\nProtobuf library provides support to pack/unpack Any values in the form\nof utility functions or additional generated methods of the Any type.\n\nExample 1: Pack and unpack a message in C++.\n\n    Foo foo = ...;\n    Any any;\n    any.PackFrom(foo);\n    ...\n    if (any.UnpackTo(&foo)) {\n      ...\n    }\n\nExample 2: Pack and unpack a message in Java.\n\n    Foo foo = ...;\n    Any any = Any.pack(foo);\n    ...\n    if (any.is(Foo.class)) {\n      foo = any.unpack(Foo.class);\n    }\n\n Example 3: Pack and unpack a message in Python.\n\n    foo = Foo(...)\n    any = Any()\n    any.Pack(foo)\n    ...\n    if any.Is(Foo.DESCRIPTOR):\n      any.Unpack(foo)\n      ...\n\n Example 4: Pack and unpack a message in Go\n\n     foo := &pb.Foo{...}\n     any, err := anypb.New(foo)\n     if err != nil {\n       ...\n     }\n     ...\n     foo := &pb.Foo{}\n     if err := any.UnmarshalTo(foo); err != nil {\n       ...\n     }\n\nThe pack methods provided by protobuf library will by default use\n'type.googleapis.com/full.type.name' as the type URL and the unpack\nmethods only use the fully qualified type name after the last '/'\nin the type URL, for example \"foo.bar.com/x/y.z\" will yield type\nname \"y.z\".\n\n\nJSON\n====\nThe JSON representation of an 'Any' value uses the regular\nrepresentation of the deserialized, embedded message, with an\nadditional field '@type' which contains the type URL. Example:\n\n    package google.profile;\n    message Person {\n      string first_name = 1;\n      string last_name = 2;\n    }\n\n    {\n      \"@type\": \"type.googleapis.com/google.profile.Person\",\n      \"firstName\": <string>,\n      \"lastName\": <string>\n    }\n\nIf the embedded message type is well-known and has a custom JSON\nrepresentation, that representation will be embedded adding a field\n'value' which holds the custom JSON in addition to the '@type'\nfield. Example (for message [google.protobuf.Duration][]):\n\n    {\n      \"@type\": \"type.googleapis.com/google.protobuf.Duration\",\n      \"value\": \"1.212s\"\n    }"},"authSaveSecretRequest":{"type":"object","properties":{"secret":{"$ref":"#/components/schemas/data_sourceSecret"},"secretKey":{"type":"string","description":"Your data source's secret key."}},"required":["secret","secretKey"]},"data_sourceSecret":{"type":"object","properties":{"id":{"type":"string","description":"A unique ID for the secret. Note: will be autogenerated if not populated."},"secretType":{"type":"string","description":"Identifier for your data source."},"expiresAt":{"type":"string","format":"date-time","description":"The expiry date for your secret, in ISO 8601 format."},"accessKey":{"type":"string","description":"Your data source's access key."},"params":{"type":"object","additionalProperties":{"type":"string"},"description":"Extra parameters (if any) for your data source."},"name":{"type":"string","description":"A descriptive name for your secret."}},"required":["secretType","accessKey"]}}},"paths":{"/secrets":{"post":{"summary":"Create or update a secret","description":"Save a secret for data sources/destinations usage","operationId":"Auth_SaveSecret","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/commonGenericResponse"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/commonGenericResponse"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"tags":["secrets"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/authSaveSecretRequest"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/authSaveSecretRequest"}}},"required":true}}}}}
```

***

## List available secrets

> List available secrets

```json
{"openapi":"3.1.1","info":{"title":"ByteNite auth API","version":"0.1"},"tags":[],"servers":[{"url":"https://api.bytenite.com/v1/auth"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"authListSecretsResponse":{"type":"object","properties":{"secrets":{"type":"array","items":{"$ref":"#/components/schemas/data_sourceSecret"}}}},"data_sourceSecret":{"type":"object","properties":{"id":{"type":"string","description":"A unique ID for the secret. Note: will be autogenerated if not populated."},"secretType":{"type":"string","description":"Identifier for your data source."},"expiresAt":{"type":"string","format":"date-time","description":"The expiry date for your secret, in ISO 8601 format."},"accessKey":{"type":"string","description":"Your data source's access key."},"params":{"type":"object","additionalProperties":{"type":"string"},"description":"Extra parameters (if any) for your data source."},"name":{"type":"string","description":"A descriptive name for your secret."}},"required":["secretType","accessKey"]},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}},"protobufAny":{"type":"object","properties":{"@type":{"type":"string","description":"A URL/resource name that uniquely identifies the type of the serialized\nprotocol buffer message. This string must contain at least\none \"/\" character. The last segment of the URL's path must represent\nthe fully qualified name of the type (as in\n'path/google.protobuf.Duration'). The name should be in a canonical form\n(e.g., leading \".\" is not accepted).\n\nIn practice, teams usually precompile into the binary all types that they\nexpect it to use in the context of Any. However, for URLs which use the\nscheme 'http', 'https', or no scheme, one can optionally set up a type\nserver that maps type URLs to message definitions as follows:\n\n* If no scheme is provided, 'https' is assumed.\n* An HTTP GET on the URL must yield a [google.protobuf.Type][]\n  value in binary format, or produce an error.\n* Applications are allowed to cache lookup results based on the\n  URL, or have them precompiled into a binary to avoid any\n  lookup. Therefore, binary compatibility needs to be preserved\n  on changes to types. (Use versioned type names to manage\n  breaking changes.)\n\nNote: this functionality is not currently available in the official\nprotobuf release, and it is not used for type URLs beginning with\ntype.googleapis.com.\n\nSchemes other than 'http', 'https' (or the empty scheme) might be\nused with implementation specific semantics."}},"additionalProperties":{},"description":"'Any' contains an arbitrary serialized protocol buffer message along with a\nURL that describes the type of the serialized message.\n\nProtobuf library provides support to pack/unpack Any values in the form\nof utility functions or additional generated methods of the Any type.\n\nExample 1: Pack and unpack a message in C++.\n\n    Foo foo = ...;\n    Any any;\n    any.PackFrom(foo);\n    ...\n    if (any.UnpackTo(&foo)) {\n      ...\n    }\n\nExample 2: Pack and unpack a message in Java.\n\n    Foo foo = ...;\n    Any any = Any.pack(foo);\n    ...\n    if (any.is(Foo.class)) {\n      foo = any.unpack(Foo.class);\n    }\n\n Example 3: Pack and unpack a message in Python.\n\n    foo = Foo(...)\n    any = Any()\n    any.Pack(foo)\n    ...\n    if any.Is(Foo.DESCRIPTOR):\n      any.Unpack(foo)\n      ...\n\n Example 4: Pack and unpack a message in Go\n\n     foo := &pb.Foo{...}\n     any, err := anypb.New(foo)\n     if err != nil {\n       ...\n     }\n     ...\n     foo := &pb.Foo{}\n     if err := any.UnmarshalTo(foo); err != nil {\n       ...\n     }\n\nThe pack methods provided by protobuf library will by default use\n'type.googleapis.com/full.type.name' as the type URL and the unpack\nmethods only use the fully qualified type name after the last '/'\nin the type URL, for example \"foo.bar.com/x/y.z\" will yield type\nname \"y.z\".\n\n\nJSON\n====\nThe JSON representation of an 'Any' value uses the regular\nrepresentation of the deserialized, embedded message, with an\nadditional field '@type' which contains the type URL. Example:\n\n    package google.profile;\n    message Person {\n      string first_name = 1;\n      string last_name = 2;\n    }\n\n    {\n      \"@type\": \"type.googleapis.com/google.profile.Person\",\n      \"firstName\": <string>,\n      \"lastName\": <string>\n    }\n\nIf the embedded message type is well-known and has a custom JSON\nrepresentation, that representation will be embedded adding a field\n'value' which holds the custom JSON in addition to the '@type'\nfield. Example (for message [google.protobuf.Duration][]):\n\n    {\n      \"@type\": \"type.googleapis.com/google.protobuf.Duration\",\n      \"value\": \"1.212s\"\n    }"}}},"paths":{"/secrets":{"get":{"summary":"List available secrets","description":"List available secrets","operationId":"Auth_ListSecrets","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/authListSecretsResponse"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/authListSecretsResponse"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"parameters":[{"schema":{"type":"string"},"name":"secretType","description":"The type of the secret","in":"query","required":false}],"tags":["secrets"]}}}}
```

***

## Remove a secret

> Remove a secret

```json
{"openapi":"3.1.1","info":{"title":"ByteNite auth API","version":"0.1"},"tags":[],"servers":[{"url":"https://api.bytenite.com/v1/auth"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"commonGenericResponse":{"type":"object","properties":{"ok":{"type":"boolean","description":"True if the request was successful."},"requestId":{"type":"string","description":"Internal request identifier for tracing or support."},"message":{"type":"string","description":"Additional message providing status or context."},"error":{"$ref":"#/components/schemas/commonError","description":"Optional error information if the request failed."}}},"commonError":{"type":"object","properties":{"code":{"type":"integer","format":"int64","description":"Error code if the request failed."},"message":{"type":"string","description":"Short description of the error if occurred."},"description":{"type":"string","description":"Full detailed explanation of the error if applicable."}}},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}},"protobufAny":{"type":"object","properties":{"@type":{"type":"string","description":"A URL/resource name that uniquely identifies the type of the serialized\nprotocol buffer message. This string must contain at least\none \"/\" character. The last segment of the URL's path must represent\nthe fully qualified name of the type (as in\n'path/google.protobuf.Duration'). The name should be in a canonical form\n(e.g., leading \".\" is not accepted).\n\nIn practice, teams usually precompile into the binary all types that they\nexpect it to use in the context of Any. However, for URLs which use the\nscheme 'http', 'https', or no scheme, one can optionally set up a type\nserver that maps type URLs to message definitions as follows:\n\n* If no scheme is provided, 'https' is assumed.\n* An HTTP GET on the URL must yield a [google.protobuf.Type][]\n  value in binary format, or produce an error.\n* Applications are allowed to cache lookup results based on the\n  URL, or have them precompiled into a binary to avoid any\n  lookup. Therefore, binary compatibility needs to be preserved\n  on changes to types. (Use versioned type names to manage\n  breaking changes.)\n\nNote: this functionality is not currently available in the official\nprotobuf release, and it is not used for type URLs beginning with\ntype.googleapis.com.\n\nSchemes other than 'http', 'https' (or the empty scheme) might be\nused with implementation specific semantics."}},"additionalProperties":{},"description":"'Any' contains an arbitrary serialized protocol buffer message along with a\nURL that describes the type of the serialized message.\n\nProtobuf library provides support to pack/unpack Any values in the form\nof utility functions or additional generated methods of the Any type.\n\nExample 1: Pack and unpack a message in C++.\n\n    Foo foo = ...;\n    Any any;\n    any.PackFrom(foo);\n    ...\n    if (any.UnpackTo(&foo)) {\n      ...\n    }\n\nExample 2: Pack and unpack a message in Java.\n\n    Foo foo = ...;\n    Any any = Any.pack(foo);\n    ...\n    if (any.is(Foo.class)) {\n      foo = any.unpack(Foo.class);\n    }\n\n Example 3: Pack and unpack a message in Python.\n\n    foo = Foo(...)\n    any = Any()\n    any.Pack(foo)\n    ...\n    if any.Is(Foo.DESCRIPTOR):\n      any.Unpack(foo)\n      ...\n\n Example 4: Pack and unpack a message in Go\n\n     foo := &pb.Foo{...}\n     any, err := anypb.New(foo)\n     if err != nil {\n       ...\n     }\n     ...\n     foo := &pb.Foo{}\n     if err := any.UnmarshalTo(foo); err != nil {\n       ...\n     }\n\nThe pack methods provided by protobuf library will by default use\n'type.googleapis.com/full.type.name' as the type URL and the unpack\nmethods only use the fully qualified type name after the last '/'\nin the type URL, for example \"foo.bar.com/x/y.z\" will yield type\nname \"y.z\".\n\n\nJSON\n====\nThe JSON representation of an 'Any' value uses the regular\nrepresentation of the deserialized, embedded message, with an\nadditional field '@type' which contains the type URL. Example:\n\n    package google.profile;\n    message Person {\n      string first_name = 1;\n      string last_name = 2;\n    }\n\n    {\n      \"@type\": \"type.googleapis.com/google.profile.Person\",\n      \"firstName\": <string>,\n      \"lastName\": <string>\n    }\n\nIf the embedded message type is well-known and has a custom JSON\nrepresentation, that representation will be embedded adding a field\n'value' which holds the custom JSON in addition to the '@type'\nfield. Example (for message [google.protobuf.Duration][]):\n\n    {\n      \"@type\": \"type.googleapis.com/google.protobuf.Duration\",\n      \"value\": \"1.212s\"\n    }"}}},"paths":{"/secrets/{secretType}/{id}":{"delete":{"summary":"Remove a secret","description":"Remove a secret","operationId":"Auth_DeleteSecret","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/commonGenericResponse"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/commonGenericResponse"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"parameters":[{"schema":{"type":"string"},"name":"secretType","description":"The type of the secret","in":"path","required":true},{"schema":{"type":"string"},"name":"id","description":"The ID of the secret","in":"path","required":true}],"tags":["secrets"]}}}}
```


# User

***

## Generic information about user

> Get id, email, name, image and activation status

```json
{"openapi":"3.1.1","info":{"title":"ByteNite auth API","version":"0.1"},"tags":[],"servers":[{"url":"https://api.bytenite.com/v1/auth"}],"security":[{"BearerAuth":["read"]}],"components":{"securitySchemes":{"BearerAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"authUserInfoResponse":{"type":"object","properties":{"user":{"$ref":"#/components/schemas/userUser"}}},"userUser":{"type":"object","properties":{"id":{"type":"string","title":"User ID"},"createdAt":{"type":"string","format":"date-time","title":"User's account creation date"},"lastLogin":{"type":"string","format":"date-time","title":"User's last login date"},"displayName":{"type":"string","title":"User's display name"},"email":{"type":"string","title":"User's email address"},"settings":{"type":"object","title":"User's settings, stored as a JSON object"},"photoUrl":{"type":"string","title":"User's profile photo URL"},"providerId":{"type":"string","title":"Provider ID"},"emailVerified":{"type":"boolean","title":"User's email verification status"},"customClaims":{"type":"object","title":"User's custom claims"},"role":{"$ref":"#/components/schemas/commonRole","title":"User's role"},"firstName":{"type":"string","title":"User's first name"},"lastName":{"type":"string","title":"User's last name"},"contactInfo":{"$ref":"#/components/schemas/userContactInfo","title":"User's contact information, including company, job title, phone number, and address"},"disabled":{"type":"boolean","title":"Whether the user account is disabled"},"isOnboarded":{"type":"boolean","title":"Whether the user has completed onboarding"},"onboardingInfo":{"type":"array","items":{"$ref":"#/components/schemas/userOnboardingInfo"},"title":"Onboarding information filled out by the user"},"userName":{"type":"string","title":"User's username"}},"title":"These tables relate to attributes specific to the user"},"commonRole":{"type":"string","enum":["ROLE_NONE","ROLE_USER","ROLE_DEVELOPER","ROLE_ADMIN"],"default":"ROLE_NONE"},"userContactInfo":{"type":"object","properties":{"company":{"type":"string","title":"company name"},"jobTitle":{"type":"string","title":"job title"},"phoneNumber":{"type":"string","title":"phone number"},"address1":{"type":"string","title":"address line 1"},"address2":{"type":"string","title":"address line 2"},"city":{"type":"string","title":"city name"},"state":{"type":"string","title":"state name"},"zip":{"type":"string","title":"zip code"},"country":{"type":"string","title":"country name"}}},"userOnboardingInfo":{"type":"object","properties":{"step":{"type":"integer","format":"int32","title":"To indicate the current step in the onboarding process"},"answer":{"type":"object","title":"Capture user's answer for that particular step"}}},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}},"protobufAny":{"type":"object","properties":{"@type":{"type":"string","description":"A URL/resource name that uniquely identifies the type of the serialized\nprotocol buffer message. This string must contain at least\none \"/\" character. The last segment of the URL's path must represent\nthe fully qualified name of the type (as in\n'path/google.protobuf.Duration'). The name should be in a canonical form\n(e.g., leading \".\" is not accepted).\n\nIn practice, teams usually precompile into the binary all types that they\nexpect it to use in the context of Any. However, for URLs which use the\nscheme 'http', 'https', or no scheme, one can optionally set up a type\nserver that maps type URLs to message definitions as follows:\n\n* If no scheme is provided, 'https' is assumed.\n* An HTTP GET on the URL must yield a [google.protobuf.Type][]\n  value in binary format, or produce an error.\n* Applications are allowed to cache lookup results based on the\n  URL, or have them precompiled into a binary to avoid any\n  lookup. Therefore, binary compatibility needs to be preserved\n  on changes to types. (Use versioned type names to manage\n  breaking changes.)\n\nNote: this functionality is not currently available in the official\nprotobuf release, and it is not used for type URLs beginning with\ntype.googleapis.com.\n\nSchemes other than 'http', 'https' (or the empty scheme) might be\nused with implementation specific semantics."}},"additionalProperties":{},"description":"'Any' contains an arbitrary serialized protocol buffer message along with a\nURL that describes the type of the serialized message.\n\nProtobuf library provides support to pack/unpack Any values in the form\nof utility functions or additional generated methods of the Any type.\n\nExample 1: Pack and unpack a message in C++.\n\n    Foo foo = ...;\n    Any any;\n    any.PackFrom(foo);\n    ...\n    if (any.UnpackTo(&foo)) {\n      ...\n    }\n\nExample 2: Pack and unpack a message in Java.\n\n    Foo foo = ...;\n    Any any = Any.pack(foo);\n    ...\n    if (any.is(Foo.class)) {\n      foo = any.unpack(Foo.class);\n    }\n\n Example 3: Pack and unpack a message in Python.\n\n    foo = Foo(...)\n    any = Any()\n    any.Pack(foo)\n    ...\n    if any.Is(Foo.DESCRIPTOR):\n      any.Unpack(foo)\n      ...\n\n Example 4: Pack and unpack a message in Go\n\n     foo := &pb.Foo{...}\n     any, err := anypb.New(foo)\n     if err != nil {\n       ...\n     }\n     ...\n     foo := &pb.Foo{}\n     if err := any.UnmarshalTo(foo); err != nil {\n       ...\n     }\n\nThe pack methods provided by protobuf library will by default use\n'type.googleapis.com/full.type.name' as the type URL and the unpack\nmethods only use the fully qualified type name after the last '/'\nin the type URL, for example \"foo.bar.com/x/y.z\" will yield type\nname \"y.z\".\n\n\nJSON\n====\nThe JSON representation of an 'Any' value uses the regular\nrepresentation of the deserialized, embedded message, with an\nadditional field '@type' which contains the type URL. Example:\n\n    package google.profile;\n    message Person {\n      string first_name = 1;\n      string last_name = 2;\n    }\n\n    {\n      \"@type\": \"type.googleapis.com/google.profile.Person\",\n      \"firstName\": <string>,\n      \"lastName\": <string>\n    }\n\nIf the embedded message type is well-known and has a custom JSON\nrepresentation, that representation will be embedded adding a field\n'value' which holds the custom JSON in addition to the '@type'\nfield. Example (for message [google.protobuf.Duration][]):\n\n    {\n      \"@type\": \"type.googleapis.com/google.protobuf.Duration\",\n      \"value\": \"1.212s\"\n    }"}}},"paths":{"/user":{"get":{"summary":"Generic information about user","description":"Get id, email, name, image and activation status","operationId":"Auth_UserInfo","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/authUserInfoResponse"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/authUserInfoResponse"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"tags":["user"]}}}}
```

***

## Set user info

> Set editable user info

```json
{"openapi":"3.1.1","info":{"title":"ByteNite auth API","version":"0.1"},"tags":[],"servers":[{"url":"https://api.bytenite.com/v1/auth"}],"security":[{"BearerAuth":["read","write"]}],"components":{"securitySchemes":{"BearerAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"authUserInfoResponse":{"type":"object","properties":{"user":{"$ref":"#/components/schemas/userUser"}}},"userUser":{"type":"object","properties":{"id":{"type":"string","title":"User ID"},"createdAt":{"type":"string","format":"date-time","title":"User's account creation date"},"lastLogin":{"type":"string","format":"date-time","title":"User's last login date"},"displayName":{"type":"string","title":"User's display name"},"email":{"type":"string","title":"User's email address"},"settings":{"type":"object","title":"User's settings, stored as a JSON object"},"photoUrl":{"type":"string","title":"User's profile photo URL"},"providerId":{"type":"string","title":"Provider ID"},"emailVerified":{"type":"boolean","title":"User's email verification status"},"customClaims":{"type":"object","title":"User's custom claims"},"role":{"$ref":"#/components/schemas/commonRole","title":"User's role"},"firstName":{"type":"string","title":"User's first name"},"lastName":{"type":"string","title":"User's last name"},"contactInfo":{"$ref":"#/components/schemas/userContactInfo","title":"User's contact information, including company, job title, phone number, and address"},"disabled":{"type":"boolean","title":"Whether the user account is disabled"},"isOnboarded":{"type":"boolean","title":"Whether the user has completed onboarding"},"onboardingInfo":{"type":"array","items":{"$ref":"#/components/schemas/userOnboardingInfo"},"title":"Onboarding information filled out by the user"},"userName":{"type":"string","title":"User's username"}},"title":"These tables relate to attributes specific to the user"},"commonRole":{"type":"string","enum":["ROLE_NONE","ROLE_USER","ROLE_DEVELOPER","ROLE_ADMIN"],"default":"ROLE_NONE"},"userContactInfo":{"type":"object","properties":{"company":{"type":"string","title":"company name"},"jobTitle":{"type":"string","title":"job title"},"phoneNumber":{"type":"string","title":"phone number"},"address1":{"type":"string","title":"address line 1"},"address2":{"type":"string","title":"address line 2"},"city":{"type":"string","title":"city name"},"state":{"type":"string","title":"state name"},"zip":{"type":"string","title":"zip code"},"country":{"type":"string","title":"country name"}}},"userOnboardingInfo":{"type":"object","properties":{"step":{"type":"integer","format":"int32","title":"To indicate the current step in the onboarding process"},"answer":{"type":"object","title":"Capture user's answer for that particular step"}}},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}},"protobufAny":{"type":"object","properties":{"@type":{"type":"string","description":"A URL/resource name that uniquely identifies the type of the serialized\nprotocol buffer message. This string must contain at least\none \"/\" character. The last segment of the URL's path must represent\nthe fully qualified name of the type (as in\n'path/google.protobuf.Duration'). The name should be in a canonical form\n(e.g., leading \".\" is not accepted).\n\nIn practice, teams usually precompile into the binary all types that they\nexpect it to use in the context of Any. However, for URLs which use the\nscheme 'http', 'https', or no scheme, one can optionally set up a type\nserver that maps type URLs to message definitions as follows:\n\n* If no scheme is provided, 'https' is assumed.\n* An HTTP GET on the URL must yield a [google.protobuf.Type][]\n  value in binary format, or produce an error.\n* Applications are allowed to cache lookup results based on the\n  URL, or have them precompiled into a binary to avoid any\n  lookup. Therefore, binary compatibility needs to be preserved\n  on changes to types. (Use versioned type names to manage\n  breaking changes.)\n\nNote: this functionality is not currently available in the official\nprotobuf release, and it is not used for type URLs beginning with\ntype.googleapis.com.\n\nSchemes other than 'http', 'https' (or the empty scheme) might be\nused with implementation specific semantics."}},"additionalProperties":{},"description":"'Any' contains an arbitrary serialized protocol buffer message along with a\nURL that describes the type of the serialized message.\n\nProtobuf library provides support to pack/unpack Any values in the form\nof utility functions or additional generated methods of the Any type.\n\nExample 1: Pack and unpack a message in C++.\n\n    Foo foo = ...;\n    Any any;\n    any.PackFrom(foo);\n    ...\n    if (any.UnpackTo(&foo)) {\n      ...\n    }\n\nExample 2: Pack and unpack a message in Java.\n\n    Foo foo = ...;\n    Any any = Any.pack(foo);\n    ...\n    if (any.is(Foo.class)) {\n      foo = any.unpack(Foo.class);\n    }\n\n Example 3: Pack and unpack a message in Python.\n\n    foo = Foo(...)\n    any = Any()\n    any.Pack(foo)\n    ...\n    if any.Is(Foo.DESCRIPTOR):\n      any.Unpack(foo)\n      ...\n\n Example 4: Pack and unpack a message in Go\n\n     foo := &pb.Foo{...}\n     any, err := anypb.New(foo)\n     if err != nil {\n       ...\n     }\n     ...\n     foo := &pb.Foo{}\n     if err := any.UnmarshalTo(foo); err != nil {\n       ...\n     }\n\nThe pack methods provided by protobuf library will by default use\n'type.googleapis.com/full.type.name' as the type URL and the unpack\nmethods only use the fully qualified type name after the last '/'\nin the type URL, for example \"foo.bar.com/x/y.z\" will yield type\nname \"y.z\".\n\n\nJSON\n====\nThe JSON representation of an 'Any' value uses the regular\nrepresentation of the deserialized, embedded message, with an\nadditional field '@type' which contains the type URL. Example:\n\n    package google.profile;\n    message Person {\n      string first_name = 1;\n      string last_name = 2;\n    }\n\n    {\n      \"@type\": \"type.googleapis.com/google.profile.Person\",\n      \"firstName\": <string>,\n      \"lastName\": <string>\n    }\n\nIf the embedded message type is well-known and has a custom JSON\nrepresentation, that representation will be embedded adding a field\n'value' which holds the custom JSON in addition to the '@type'\nfield. Example (for message [google.protobuf.Duration][]):\n\n    {\n      \"@type\": \"type.googleapis.com/google.protobuf.Duration\",\n      \"value\": \"1.212s\"\n    }"},"authSetUserInfoRequest":{"type":"object","properties":{"contactInfo":{"$ref":"#/components/schemas/userContactInfo"},"firstName":{"type":"string","title":"User's first name"},"lastName":{"type":"string","title":"User's last name"},"userName":{"type":"string","title":"User's username"},"onboardingInfo":{"type":"array","items":{"$ref":"#/components/schemas/userOnboardingInfo"},"title":"Onboarding information filled out by the user"}}}}},"paths":{"/user":{"patch":{"summary":"Set user info","description":"Set editable user info","operationId":"Auth_SetUserInfo","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/authUserInfoResponse"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/authUserInfoResponse"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"tags":["user"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/authSetUserInfoRequest"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/authSetUserInfoRequest"}}},"required":true}}}}}
```


# Developer API

## About

* Base URL: `https://api.bytenite.com/v1/dev`
* Version: `v1`
* Swagger Docs: <https://api.bytenite.com/v1/dev/docs/>
* Specification: <https://api.bytenite.com/v1/dev/docs/swagger.json>

***

## Retrieve information about service

> Server software version and important messages

```json
{"openapi":"3.1.1","info":{"title":"ByteNite developers API","version":"0.1"},"tags":[],"servers":[{"url":"https://api.bytenite.com/v1/dev"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"developerServerInfoResponse":{"type":"object","properties":{"version":{"$ref":"#/components/schemas/commonVersion"},"messages":{"type":"object","additionalProperties":{"type":"string"}}}},"commonVersion":{"type":"object","properties":{"major":{"type":"integer","format":"int64"},"minor":{"type":"integer","format":"int64"},"tag":{"type":"string"}},"description":"A semantic version for managing updates."},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}},"protobufAny":{"type":"object","properties":{"@type":{"type":"string"}},"additionalProperties":{}}}},"paths":{"/info":{"get":{"summary":"Retrieve information about service","description":"Server software version and important messages","operationId":"Developer_Info","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/developerServerInfoResponse"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/developerServerInfoResponse"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"tags":["info"]}}}}
```


# Apps

<table data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Metadata</strong></td><td>Fetch app's metadata like name and version.</td><td><a href="/api-reference/developer-api/apps/metadata">Metadata</a></td></tr><tr><td><strong>Push</strong></td><td>Push a local app directory to ByteNite.</td><td><a href="/api-reference/developer-api/apps/push">Push</a></td></tr><tr><td><strong>Manage</strong></td><td>Activate, deactivate, and delete apps.</td><td><a href="/api-reference/developer-api/apps/metadata">Metadata</a></td></tr><tr><td><strong>Pull</strong></td><td>Download a ByteNite app locally.</td><td><a href="/api-reference/developer-api/apps/pull">Pull</a></td></tr></tbody></table>


# Metadata

***

## Get distributed apps

> List all distributed apps created by the user.\
> \
> Use this endpoint to fetch apps created by the user.

```json
{"openapi":"3.1.1","info":{"title":"ByteNite developers API","version":"0.1"},"tags":[],"servers":[{"url":"https://api.bytenite.com/v1/dev"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"developerAppListResponse":{"type":"object","properties":{"apps":{"type":"array","items":{"$ref":"#/components/schemas/appApp"}},"pagination":{"$ref":"#/components/schemas/commonPaginatedResponse"}}},"appApp":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier assigned to the distributed app (UUID).","readOnly":true},"name":{"type":"string","description":"Human-readable name of the app."},"version":{"type":"string","title":"App version"},"owner":{"type":"string","description":"UUID of the user who owns the app."},"status":{"type":"string","description":"Status of the app, e.g., active, inactive."},"deviceRequirements":{"$ref":"#/components/schemas/commonDeviceRequirements","title":"Device requirements for running the app"},"isPublic":{"type":"boolean","description":"Indicates whether the app is publicly accessible."},"createdAt":{"type":"string","format":"date-time","description":"UTC timestamp when the app was created.","readOnly":true},"updatedAt":{"type":"string","format":"date-time","description":"UTC timestamp when the app was last updated.","readOnly":true},"platform":{"type":"string","description":"Target platform for app execution (e.g., docker)."},"hash":{"type":"string","description":"SHA256 checksum of the uploaded tar archive.","readOnly":true},"link":{"type":"string","description":"Currently contains the link to the app's source code."},"platformConfig":{"$ref":"#/components/schemas/commonPlatformConfig","title":"Platform-specific configuration"},"entrypoint":{"type":"string","description":"Main executable file or script to launch the application (e.g., main.py)."},"revision":{"type":"string","format":"int64","description":"Internal revision tracking number.","readOnly":true},"description":{"type":"string","description":"Optional free-form description of the app."},"userName":{"type":"string","description":"User name of the app owner."}},"description":"Each bytenite job is tagged to an app which describes the type of job being run."},"commonDeviceRequirements":{"type":"object","properties":{"minCpu":{"type":"number","format":"float","description":"Minimum number of vCPUs required to run the app/engine."},"minMemory":{"type":"number","format":"float","description":"Minimum amount of RAM (GB) required to run the app."},"gpu":{"type":"array","items":{"type":"string"},"description":"Array of GPU models requested to run the app/engine, in order of preference. Use the official GPU identifiers provided by the /wallet/rates endpoint. Leave blank if no GPU is required."}},"description":"DeviceRequirements represents the minimum hardware requirements for running the app/engine."},"commonPlatformConfig":{"type":"object","properties":{"container":{"type":"string","description":"Container image identifier."},"privateImage":{"type":"boolean","description":"Indicates if the container image is from a private registry."},"username":{"type":"string","description":"Username for accessing a private container registry (if applicable)."},"token":{"type":"string","description":"Authentication token for accessing a private container registry (if applicable)."},"secrets":{"type":"array","items":{"type":"string"},"description":"List of secret names to be injected into the container as environment variables."}},"title":"PlatformConfig represents configuration for a platform"},"commonPaginatedResponse":{"type":"object","properties":{"total":{"type":"integer","format":"int64","description":"The total number of transactions available."},"offset":{"type":"integer","format":"int64","description":"The starting position of the current page of results, starting from 0."},"hasPrevious":{"type":"boolean","description":"A boolean value (True/False) indicating whether there's a previous page of results. False if the current page is the first page."},"hasNext":{"type":"boolean","description":"A boolean value indicating whether there's a next page of results."}},"description":"This section provides information about how the results are divided into pages."},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}},"protobufAny":{"type":"object","properties":{"@type":{"type":"string"}},"additionalProperties":{}}}},"paths":{"/apps":{"get":{"summary":"Get distributed apps","description":"List all distributed apps created by the user.\n\nUse this endpoint to fetch apps created by the user.","operationId":"Developer_GetApps","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/developerAppListResponse"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/developerAppListResponse"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"parameters":[{"schema":{"type":"string"},"name":"orderBy","description":"Field name to sort apps by (e.g., createdAt).","in":"query","required":false},{"schema":{"type":"integer","format":"int64"},"name":"pagination.limit","description":"Number of rows to return per page.","in":"query","required":false},{"schema":{"type":"integer","format":"int64"},"name":"pagination.offset","description":"Number of rows to skip before starting to collect the result set.","in":"query","required":false},{"schema":{"type":"boolean"},"name":"isPublic","description":"Filter public apps only","in":"query","required":false}],"tags":["apps"]}}}}
```

***

## Get the latest app details

> Get the latest app de

```json
{"openapi":"3.1.1","info":{"title":"ByteNite developers API","version":"0.1"},"tags":[],"servers":[{"url":"https://api.bytenite.com/v1/dev"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"developerAppResponse":{"type":"object","properties":{"app":{"$ref":"#/components/schemas/appApp"}},"title":"Responses"},"appApp":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier assigned to the distributed app (UUID).","readOnly":true},"name":{"type":"string","description":"Human-readable name of the app."},"version":{"type":"string","title":"App version"},"owner":{"type":"string","description":"UUID of the user who owns the app."},"status":{"type":"string","description":"Status of the app, e.g., active, inactive."},"deviceRequirements":{"$ref":"#/components/schemas/commonDeviceRequirements","title":"Device requirements for running the app"},"isPublic":{"type":"boolean","description":"Indicates whether the app is publicly accessible."},"createdAt":{"type":"string","format":"date-time","description":"UTC timestamp when the app was created.","readOnly":true},"updatedAt":{"type":"string","format":"date-time","description":"UTC timestamp when the app was last updated.","readOnly":true},"platform":{"type":"string","description":"Target platform for app execution (e.g., docker)."},"hash":{"type":"string","description":"SHA256 checksum of the uploaded tar archive.","readOnly":true},"link":{"type":"string","description":"Currently contains the link to the app's source code."},"platformConfig":{"$ref":"#/components/schemas/commonPlatformConfig","title":"Platform-specific configuration"},"entrypoint":{"type":"string","description":"Main executable file or script to launch the application (e.g., main.py)."},"revision":{"type":"string","format":"int64","description":"Internal revision tracking number.","readOnly":true},"description":{"type":"string","description":"Optional free-form description of the app."},"userName":{"type":"string","description":"User name of the app owner."}},"description":"Each bytenite job is tagged to an app which describes the type of job being run."},"commonDeviceRequirements":{"type":"object","properties":{"minCpu":{"type":"number","format":"float","description":"Minimum number of vCPUs required to run the app/engine."},"minMemory":{"type":"number","format":"float","description":"Minimum amount of RAM (GB) required to run the app."},"gpu":{"type":"array","items":{"type":"string"},"description":"Array of GPU models requested to run the app/engine, in order of preference. Use the official GPU identifiers provided by the /wallet/rates endpoint. Leave blank if no GPU is required."}},"description":"DeviceRequirements represents the minimum hardware requirements for running the app/engine."},"commonPlatformConfig":{"type":"object","properties":{"container":{"type":"string","description":"Container image identifier."},"privateImage":{"type":"boolean","description":"Indicates if the container image is from a private registry."},"username":{"type":"string","description":"Username for accessing a private container registry (if applicable)."},"token":{"type":"string","description":"Authentication token for accessing a private container registry (if applicable)."},"secrets":{"type":"array","items":{"type":"string"},"description":"List of secret names to be injected into the container as environment variables."}},"title":"PlatformConfig represents configuration for a platform"},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}},"protobufAny":{"type":"object","properties":{"@type":{"type":"string"}},"additionalProperties":{}}}},"paths":{"/apps/{appTag}":{"get":{"summary":"Get the latest app details","description":"Get the latest app de","operationId":"Developer_GetAppByTag","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/developerAppResponse"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/developerAppResponse"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"parameters":[{"schema":{"type":"string"},"name":"appTag","description":"Unique tag of the app","in":"path","required":true}],"tags":["apps"]}}}}
```

***

## Get status of app

> Get status of app

```json
{"openapi":"3.1.1","info":{"title":"ByteNite developers API","version":"0.1"},"tags":[],"servers":[{"url":"https://api.bytenite.com/v1/dev"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"commonGenericResponse":{"type":"object","properties":{"ok":{"type":"boolean","description":"True if the request was successful."},"requestId":{"type":"string","description":"Internal request identifier for tracing or support."},"message":{"type":"string","description":"Additional message providing status or context."},"error":{"$ref":"#/components/schemas/commonError","description":"Optional error information if the request failed."}}},"commonError":{"type":"object","properties":{"code":{"type":"integer","format":"int64","description":"Error code if the request failed."},"message":{"type":"string","description":"Short description of the error if occurred."},"description":{"type":"string","description":"Full detailed explanation of the error if applicable."}}},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}},"protobufAny":{"type":"object","properties":{"@type":{"type":"string"}},"additionalProperties":{}}}},"paths":{"/apps/{appTag}/status":{"get":{"summary":"Get status of app","description":"Get status of app","operationId":"Developer_GetAppStatus","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/commonGenericResponse"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/commonGenericResponse"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"parameters":[{"schema":{"type":"string"},"name":"appTag","description":"Unique tag of the app","in":"path","required":true}],"tags":["apps"]}}}}
```


# Push

***

## Upload a distributed app

> Upload a distributed app to the server

```json
{"openapi":"3.1.1","info":{"title":"ByteNite developers API","version":"0.1"},"tags":[],"servers":[{"url":"https://api.bytenite.com/v1/dev"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"appApp":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier assigned to the distributed app (UUID).","readOnly":true},"name":{"type":"string","description":"Human-readable name of the app."},"version":{"type":"string","title":"App version"},"owner":{"type":"string","description":"UUID of the user who owns the app."},"status":{"type":"string","description":"Status of the app, e.g., active, inactive."},"deviceRequirements":{"$ref":"#/components/schemas/commonDeviceRequirements","title":"Device requirements for running the app"},"isPublic":{"type":"boolean","description":"Indicates whether the app is publicly accessible."},"createdAt":{"type":"string","format":"date-time","description":"UTC timestamp when the app was created.","readOnly":true},"updatedAt":{"type":"string","format":"date-time","description":"UTC timestamp when the app was last updated.","readOnly":true},"platform":{"type":"string","description":"Target platform for app execution (e.g., docker)."},"hash":{"type":"string","description":"SHA256 checksum of the uploaded tar archive.","readOnly":true},"link":{"type":"string","description":"Currently contains the link to the app's source code."},"platformConfig":{"$ref":"#/components/schemas/commonPlatformConfig","title":"Platform-specific configuration"},"entrypoint":{"type":"string","description":"Main executable file or script to launch the application (e.g., main.py)."},"revision":{"type":"string","format":"int64","description":"Internal revision tracking number.","readOnly":true},"description":{"type":"string","description":"Optional free-form description of the app."},"userName":{"type":"string","description":"User name of the app owner."}},"description":"Each bytenite job is tagged to an app which describes the type of job being run."},"commonDeviceRequirements":{"type":"object","properties":{"minCpu":{"type":"number","format":"float","description":"Minimum number of vCPUs required to run the app/engine."},"minMemory":{"type":"number","format":"float","description":"Minimum amount of RAM (GB) required to run the app."},"gpu":{"type":"array","items":{"type":"string"},"description":"Array of GPU models requested to run the app/engine, in order of preference. Use the official GPU identifiers provided by the /wallet/rates endpoint. Leave blank if no GPU is required."}},"description":"DeviceRequirements represents the minimum hardware requirements for running the app/engine."},"commonPlatformConfig":{"type":"object","properties":{"container":{"type":"string","description":"Container image identifier."},"privateImage":{"type":"boolean","description":"Indicates if the container image is from a private registry."},"username":{"type":"string","description":"Username for accessing a private container registry (if applicable)."},"token":{"type":"string","description":"Authentication token for accessing a private container registry (if applicable)."},"secrets":{"type":"array","items":{"type":"string"},"description":"List of secret names to be injected into the container as environment variables."}},"title":"PlatformConfig represents configuration for a platform"},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}},"protobufAny":{"type":"object","properties":{"@type":{"type":"string"}},"additionalProperties":{}},"developerUploadAppRequest":{"type":"object","properties":{"data":{"type":"string","description":"Base64-encoded tar archive containing application code, configuration, and dependencies.","contentEncoding":"base64"}},"required":["data"]}}},"paths":{"/apps":{"post":{"summary":"Upload a distributed app","description":"Upload a distributed app to the server","operationId":"Developer_UploadApp","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/appApp"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/appApp"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"tags":["apps"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/developerUploadAppRequest"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/developerUploadAppRequest"}}},"required":true}}}}}
```


# Manage

***

## Activate a distributed app

> Activate a distributed app

```json
{"openapi":"3.1.1","info":{"title":"ByteNite developers API","version":"0.1"},"tags":[],"servers":[{"url":"https://api.bytenite.com/v1/dev"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"commonGenericResponse":{"type":"object","properties":{"ok":{"type":"boolean","description":"True if the request was successful."},"requestId":{"type":"string","description":"Internal request identifier for tracing or support."},"message":{"type":"string","description":"Additional message providing status or context."},"error":{"$ref":"#/components/schemas/commonError","description":"Optional error information if the request failed."}}},"commonError":{"type":"object","properties":{"code":{"type":"integer","format":"int64","description":"Error code if the request failed."},"message":{"type":"string","description":"Short description of the error if occurred."},"description":{"type":"string","description":"Full detailed explanation of the error if applicable."}}},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}},"protobufAny":{"type":"object","properties":{"@type":{"type":"string"}},"additionalProperties":{}}}},"paths":{"/apps/{appTag}/activate":{"post":{"summary":"Activate a distributed app","description":"Activate a distributed app","operationId":"Developer_ActivateApp","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/commonGenericResponse"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/commonGenericResponse"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"parameters":[{"schema":{"type":"string"},"name":"appTag","description":"Unique tag of the app","in":"path","required":true}],"tags":["apps"]}}}}
```

***

## Activate a distributed app

> Activate a distributed app

```json
{"openapi":"3.1.1","info":{"title":"ByteNite developers API","version":"0.1"},"tags":[],"servers":[{"url":"https://api.bytenite.com/v1/dev"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"commonGenericResponse":{"type":"object","properties":{"ok":{"type":"boolean","description":"True if the request was successful."},"requestId":{"type":"string","description":"Internal request identifier for tracing or support."},"message":{"type":"string","description":"Additional message providing status or context."},"error":{"$ref":"#/components/schemas/commonError","description":"Optional error information if the request failed."}}},"commonError":{"type":"object","properties":{"code":{"type":"integer","format":"int64","description":"Error code if the request failed."},"message":{"type":"string","description":"Short description of the error if occurred."},"description":{"type":"string","description":"Full detailed explanation of the error if applicable."}}},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}},"protobufAny":{"type":"object","properties":{"@type":{"type":"string"}},"additionalProperties":{}}}},"paths":{"/apps/{appTag}/deactivate":{"post":{"summary":"Activate a distributed app","description":"Activate a distributed app","operationId":"Developer_DeactivateApp","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/commonGenericResponse"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/commonGenericResponse"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"parameters":[{"schema":{"type":"string"},"name":"appTag","description":"Unique tag of the app","in":"path","required":true}],"tags":["apps"]}}}}
```


# Pull

***

## Get download link for an app

> Get download link for an app

```json
{"openapi":"3.1.1","info":{"title":"ByteNite developers API","version":"0.1"},"tags":[],"servers":[{"url":"https://api.bytenite.com/v1/dev"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"commonGenericResponse":{"type":"object","properties":{"ok":{"type":"boolean","description":"True if the request was successful."},"requestId":{"type":"string","description":"Internal request identifier for tracing or support."},"message":{"type":"string","description":"Additional message providing status or context."},"error":{"$ref":"#/components/schemas/commonError","description":"Optional error information if the request failed."}}},"commonError":{"type":"object","properties":{"code":{"type":"integer","format":"int64","description":"Error code if the request failed."},"message":{"type":"string","description":"Short description of the error if occurred."},"description":{"type":"string","description":"Full detailed explanation of the error if applicable."}}},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}},"protobufAny":{"type":"object","properties":{"@type":{"type":"string"}},"additionalProperties":{}}}},"paths":{"/apps/{appTag}/download":{"get":{"summary":"Get download link for an app","description":"Get download link for an app","operationId":"Developer_GetAppDownloadLink","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/commonGenericResponse"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/commonGenericResponse"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"parameters":[{"schema":{"type":"string"},"name":"appTag","description":"Unique tag of the app","in":"path","required":true}],"tags":["apps"]}}}}
```


# Engines


# Metadata

***

## Get engines

> List all engines owned by the user

```json
{"openapi":"3.1.1","info":{"title":"ByteNite developers API","version":"0.1"},"tags":[],"servers":[{"url":"https://api.bytenite.com/v1/dev"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"developerEngineListResponse":{"type":"object","properties":{"engines":{"type":"array","items":{"$ref":"#/components/schemas/engineEngine"}},"pagination":{"$ref":"#/components/schemas/commonPaginatedResponse"}}},"engineEngine":{"type":"object","properties":{"id":{"type":"string","title":"Unique UUID identifier for the engine"},"name":{"type":"string","title":"Name of the engine"},"version":{"type":"string","title":"Version string (e.g. \"1.2\")"},"owner":{"type":"string","title":"Owner identifier"},"type":{"type":"string","title":"Optional type of engine (e.g. \"partitioner\", \"assembler\")"},"status":{"type":"string","title":"Status of the engine (e.g. \"inactive\", \"active\")"},"description":{"type":"string","title":"Description of the engine"},"hash":{"type":"string","title":"Optional content hash for engine integrity validation"},"link":{"type":"string","title":"Link to download or access the engine"},"entrypoint":{"type":"string","title":"Entrypoint file or script (default: \"main.py\")"},"revision":{"type":"integer","format":"int32","title":"Revision number for update tracking"},"createdAt":{"type":"string","format":"date-time","title":"Timestamp of creation (ISO 8601 format)","readOnly":true},"updatedAt":{"type":"string","format":"date-time","title":"Timestamp of last update (ISO 8601 format)","readOnly":true},"deletedAt":{"type":"string","format":"date-time","title":"Timestamp of soft deletion, if applicable","readOnly":true},"platform":{"type":"string","description":"Platform identifier where the engine runs."},"platformConfig":{"$ref":"#/components/schemas/commonPlatformConfig","title":"Configuration specific to the platform"},"deviceRequirements":{"$ref":"#/components/schemas/commonDeviceRequirements","title":"Minimum hardware requirements"},"isPublic":{"type":"boolean","description":"Indicates whether the engine is publicly accessible."},"userName":{"type":"string","description":"User name of the engine owner."}},"title":"Represents custom partitioner and assembler engine and its metadata"},"commonPlatformConfig":{"type":"object","properties":{"container":{"type":"string","description":"Container image identifier."},"privateImage":{"type":"boolean","description":"Indicates if the container image is from a private registry."},"username":{"type":"string","description":"Username for accessing a private container registry (if applicable)."},"token":{"type":"string","description":"Authentication token for accessing a private container registry (if applicable)."},"secrets":{"type":"array","items":{"type":"string"},"description":"List of secret names to be injected into the container as environment variables."}},"title":"PlatformConfig represents configuration for a platform"},"commonDeviceRequirements":{"type":"object","properties":{"minCpu":{"type":"number","format":"float","description":"Minimum number of vCPUs required to run the app/engine."},"minMemory":{"type":"number","format":"float","description":"Minimum amount of RAM (GB) required to run the app."},"gpu":{"type":"array","items":{"type":"string"},"description":"Array of GPU models requested to run the app/engine, in order of preference. Use the official GPU identifiers provided by the /wallet/rates endpoint. Leave blank if no GPU is required."}},"description":"DeviceRequirements represents the minimum hardware requirements for running the app/engine."},"commonPaginatedResponse":{"type":"object","properties":{"total":{"type":"integer","format":"int64","description":"The total number of transactions available."},"offset":{"type":"integer","format":"int64","description":"The starting position of the current page of results, starting from 0."},"hasPrevious":{"type":"boolean","description":"A boolean value (True/False) indicating whether there's a previous page of results. False if the current page is the first page."},"hasNext":{"type":"boolean","description":"A boolean value indicating whether there's a next page of results."}},"description":"This section provides information about how the results are divided into pages."},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}},"protobufAny":{"type":"object","properties":{"@type":{"type":"string"}},"additionalProperties":{}}}},"paths":{"/engines":{"get":{"summary":"Get engines","description":"List all engines owned by the user","operationId":"Developer_GetEngines","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/developerEngineListResponse"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/developerEngineListResponse"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"parameters":[{"schema":{"type":"string"},"name":"orderBy","description":"Field name to sort apps by (e.g., createdAt).","in":"query","required":false},{"schema":{"type":"integer","format":"int64"},"name":"pagination.limit","description":"Number of rows to return per page.","in":"query","required":false},{"schema":{"type":"integer","format":"int64"},"name":"pagination.offset","description":"Number of rows to skip before starting to collect the result set.","in":"query","required":false},{"schema":{"type":"boolean"},"name":"isPublic","description":"Filter public engines only","in":"query","required":false}],"tags":["Engines"]}}}}
```

***

## Get an engine

> Get an engine by tag

```json
{"openapi":"3.1.1","info":{"title":"ByteNite developers API","version":"0.1"},"tags":[],"servers":[{"url":"https://api.bytenite.com/v1/dev"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"engineEngine":{"type":"object","properties":{"id":{"type":"string","title":"Unique UUID identifier for the engine"},"name":{"type":"string","title":"Name of the engine"},"version":{"type":"string","title":"Version string (e.g. \"1.2\")"},"owner":{"type":"string","title":"Owner identifier"},"type":{"type":"string","title":"Optional type of engine (e.g. \"partitioner\", \"assembler\")"},"status":{"type":"string","title":"Status of the engine (e.g. \"inactive\", \"active\")"},"description":{"type":"string","title":"Description of the engine"},"hash":{"type":"string","title":"Optional content hash for engine integrity validation"},"link":{"type":"string","title":"Link to download or access the engine"},"entrypoint":{"type":"string","title":"Entrypoint file or script (default: \"main.py\")"},"revision":{"type":"integer","format":"int32","title":"Revision number for update tracking"},"createdAt":{"type":"string","format":"date-time","title":"Timestamp of creation (ISO 8601 format)","readOnly":true},"updatedAt":{"type":"string","format":"date-time","title":"Timestamp of last update (ISO 8601 format)","readOnly":true},"deletedAt":{"type":"string","format":"date-time","title":"Timestamp of soft deletion, if applicable","readOnly":true},"platform":{"type":"string","description":"Platform identifier where the engine runs."},"platformConfig":{"$ref":"#/components/schemas/commonPlatformConfig","title":"Configuration specific to the platform"},"deviceRequirements":{"$ref":"#/components/schemas/commonDeviceRequirements","title":"Minimum hardware requirements"},"isPublic":{"type":"boolean","description":"Indicates whether the engine is publicly accessible."},"userName":{"type":"string","description":"User name of the engine owner."}},"title":"Represents custom partitioner and assembler engine and its metadata"},"commonPlatformConfig":{"type":"object","properties":{"container":{"type":"string","description":"Container image identifier."},"privateImage":{"type":"boolean","description":"Indicates if the container image is from a private registry."},"username":{"type":"string","description":"Username for accessing a private container registry (if applicable)."},"token":{"type":"string","description":"Authentication token for accessing a private container registry (if applicable)."},"secrets":{"type":"array","items":{"type":"string"},"description":"List of secret names to be injected into the container as environment variables."}},"title":"PlatformConfig represents configuration for a platform"},"commonDeviceRequirements":{"type":"object","properties":{"minCpu":{"type":"number","format":"float","description":"Minimum number of vCPUs required to run the app/engine."},"minMemory":{"type":"number","format":"float","description":"Minimum amount of RAM (GB) required to run the app."},"gpu":{"type":"array","items":{"type":"string"},"description":"Array of GPU models requested to run the app/engine, in order of preference. Use the official GPU identifiers provided by the /wallet/rates endpoint. Leave blank if no GPU is required."}},"description":"DeviceRequirements represents the minimum hardware requirements for running the app/engine."},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}},"protobufAny":{"type":"object","properties":{"@type":{"type":"string"}},"additionalProperties":{}}}},"paths":{"/engines/{engineTag}":{"get":{"summary":"Get an engine","description":"Get an engine by tag","operationId":"Developer_GetEngineByTag","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/engineEngine"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/engineEngine"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"parameters":[{"schema":{"type":"string"},"name":"engineTag","in":"path","required":true},{"schema":{"type":"string"},"name":"engineId","in":"query","required":false},{"schema":{"type":"string","contentEncoding":"base64"},"name":"engineData","in":"query","required":false},{"schema":{"type":"string"},"name":"engineLink","in":"query","required":false},{"schema":{"type":"string"},"name":"engineStatus","in":"query","required":false}],"tags":["Engines"]}}}}
```

***

## Get status of engine

> Get status of engine

```json
{"openapi":"3.1.1","info":{"title":"ByteNite developers API","version":"0.1"},"tags":[],"servers":[{"url":"https://api.bytenite.com/v1/dev"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"developerEngineMessage":{"type":"object","properties":{"engineId":{"type":"string"},"engineTag":{"type":"string"},"engineData":{"type":"string","contentEncoding":"base64"},"engineLink":{"type":"string"},"engineStatus":{"type":"string"}}},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}},"protobufAny":{"type":"object","properties":{"@type":{"type":"string"}},"additionalProperties":{}}}},"paths":{"/engines/{engineTag}/status":{"get":{"summary":"Get status of engine","description":"Get status of engine","operationId":"Developer_GetEngineStatus","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/developerEngineMessage"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/developerEngineMessage"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"parameters":[{"schema":{"type":"string"},"name":"engineTag","in":"path","required":true},{"schema":{"type":"string"},"name":"engineId","in":"query","required":false},{"schema":{"type":"string","contentEncoding":"base64"},"name":"engineData","in":"query","required":false},{"schema":{"type":"string"},"name":"engineLink","in":"query","required":false},{"schema":{"type":"string"},"name":"engineStatus","in":"query","required":false}],"tags":["Engines"]}}}}
```


# Push

***

## Upload an engine

> Upload a engine to the server

```json
{"openapi":"3.1.1","info":{"title":"ByteNite developers API","version":"0.1"},"tags":[],"servers":[{"url":"https://api.bytenite.com/v1/dev"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"engineEngine":{"type":"object","properties":{"id":{"type":"string","title":"Unique UUID identifier for the engine"},"name":{"type":"string","title":"Name of the engine"},"version":{"type":"string","title":"Version string (e.g. \"1.2\")"},"owner":{"type":"string","title":"Owner identifier"},"type":{"type":"string","title":"Optional type of engine (e.g. \"partitioner\", \"assembler\")"},"status":{"type":"string","title":"Status of the engine (e.g. \"inactive\", \"active\")"},"description":{"type":"string","title":"Description of the engine"},"hash":{"type":"string","title":"Optional content hash for engine integrity validation"},"link":{"type":"string","title":"Link to download or access the engine"},"entrypoint":{"type":"string","title":"Entrypoint file or script (default: \"main.py\")"},"revision":{"type":"integer","format":"int32","title":"Revision number for update tracking"},"createdAt":{"type":"string","format":"date-time","title":"Timestamp of creation (ISO 8601 format)","readOnly":true},"updatedAt":{"type":"string","format":"date-time","title":"Timestamp of last update (ISO 8601 format)","readOnly":true},"deletedAt":{"type":"string","format":"date-time","title":"Timestamp of soft deletion, if applicable","readOnly":true},"platform":{"type":"string","description":"Platform identifier where the engine runs."},"platformConfig":{"$ref":"#/components/schemas/commonPlatformConfig","title":"Configuration specific to the platform"},"deviceRequirements":{"$ref":"#/components/schemas/commonDeviceRequirements","title":"Minimum hardware requirements"},"isPublic":{"type":"boolean","description":"Indicates whether the engine is publicly accessible."},"userName":{"type":"string","description":"User name of the engine owner."}},"title":"Represents custom partitioner and assembler engine and its metadata"},"commonPlatformConfig":{"type":"object","properties":{"container":{"type":"string","description":"Container image identifier."},"privateImage":{"type":"boolean","description":"Indicates if the container image is from a private registry."},"username":{"type":"string","description":"Username for accessing a private container registry (if applicable)."},"token":{"type":"string","description":"Authentication token for accessing a private container registry (if applicable)."},"secrets":{"type":"array","items":{"type":"string"},"description":"List of secret names to be injected into the container as environment variables."}},"title":"PlatformConfig represents configuration for a platform"},"commonDeviceRequirements":{"type":"object","properties":{"minCpu":{"type":"number","format":"float","description":"Minimum number of vCPUs required to run the app/engine."},"minMemory":{"type":"number","format":"float","description":"Minimum amount of RAM (GB) required to run the app."},"gpu":{"type":"array","items":{"type":"string"},"description":"Array of GPU models requested to run the app/engine, in order of preference. Use the official GPU identifiers provided by the /wallet/rates endpoint. Leave blank if no GPU is required."}},"description":"DeviceRequirements represents the minimum hardware requirements for running the app/engine."},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}},"protobufAny":{"type":"object","properties":{"@type":{"type":"string"}},"additionalProperties":{}}}},"paths":{"/engines":{"post":{"summary":"Upload an engine","description":"Upload a engine to the server","operationId":"Developer_UploadEngine","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/engineEngine"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/engineEngine"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"parameters":[{"schema":{"type":"string"},"name":"engineId","in":"query","required":false},{"schema":{"type":"string"},"name":"engineTag","in":"query","required":false},{"schema":{"type":"string","contentEncoding":"base64"},"name":"engineData","in":"query","required":false},{"schema":{"type":"string"},"name":"engineLink","in":"query","required":false},{"schema":{"type":"string"},"name":"engineStatus","in":"query","required":false}],"tags":["Engines"]}}}}
```


# Manage

***

## Activate an Engine

> Activate an Engine

```json
{"openapi":"3.1.1","info":{"title":"ByteNite developers API","version":"0.1"},"tags":[],"servers":[{"url":"https://api.bytenite.com/v1/dev"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"developerEngineMessage":{"type":"object","properties":{"engineId":{"type":"string"},"engineTag":{"type":"string"},"engineData":{"type":"string","contentEncoding":"base64"},"engineLink":{"type":"string"},"engineStatus":{"type":"string"}}},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}},"protobufAny":{"type":"object","properties":{"@type":{"type":"string"}},"additionalProperties":{}}}},"paths":{"/engines/{engineTag}/activate":{"post":{"summary":"Activate an Engine","description":"Activate an Engine","operationId":"Developer_ActivateEngine","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/developerEngineMessage"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/developerEngineMessage"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"parameters":[{"schema":{"type":"string"},"name":"engineTag","in":"path","required":true},{"schema":{"type":"string"},"name":"engineId","in":"query","required":false},{"schema":{"type":"string","contentEncoding":"base64"},"name":"engineData","in":"query","required":false},{"schema":{"type":"string"},"name":"engineLink","in":"query","required":false},{"schema":{"type":"string"},"name":"engineStatus","in":"query","required":false}],"tags":["Engines"]}}}}
```

***

## Deactivate an Engine

> Deactivate an Engine

```json
{"openapi":"3.1.1","info":{"title":"ByteNite developers API","version":"0.1"},"tags":[],"servers":[{"url":"https://api.bytenite.com/v1/dev"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"developerEngineMessage":{"type":"object","properties":{"engineId":{"type":"string"},"engineTag":{"type":"string"},"engineData":{"type":"string","contentEncoding":"base64"},"engineLink":{"type":"string"},"engineStatus":{"type":"string"}}},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}},"protobufAny":{"type":"object","properties":{"@type":{"type":"string"}},"additionalProperties":{}}}},"paths":{"/engines/{engineTag}/deactivate":{"post":{"summary":"Deactivate an Engine","description":"Deactivate an Engine","operationId":"Developer_DeactivateEngine","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/developerEngineMessage"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/developerEngineMessage"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"parameters":[{"schema":{"type":"string"},"name":"engineTag","in":"path","required":true},{"schema":{"type":"string"},"name":"engineId","in":"query","required":false},{"schema":{"type":"string","contentEncoding":"base64"},"name":"engineData","in":"query","required":false},{"schema":{"type":"string"},"name":"engineLink","in":"query","required":false},{"schema":{"type":"string"},"name":"engineStatus","in":"query","required":false}],"tags":["Engines"]}}}}
```


# Pull

***

## Download an Engine

> Download an Engine

```json
{"openapi":"3.1.1","info":{"title":"ByteNite developers API","version":"0.1"},"tags":[],"servers":[{"url":"https://api.bytenite.com/v1/dev"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"developerEngineMessage":{"type":"object","properties":{"engineId":{"type":"string"},"engineTag":{"type":"string"},"engineData":{"type":"string","contentEncoding":"base64"},"engineLink":{"type":"string"},"engineStatus":{"type":"string"}}},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}},"protobufAny":{"type":"object","properties":{"@type":{"type":"string"}},"additionalProperties":{}}}},"paths":{"/engines/{engineTag}/download":{"get":{"summary":"Download an Engine","description":"Download an Engine","operationId":"Developer_GetEngineLink","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/developerEngineMessage"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/developerEngineMessage"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"parameters":[{"schema":{"type":"string"},"name":"engineTag","in":"path","required":true},{"schema":{"type":"string"},"name":"engineId","in":"query","required":false},{"schema":{"type":"string","contentEncoding":"base64"},"name":"engineData","in":"query","required":false},{"schema":{"type":"string"},"name":"engineLink","in":"query","required":false},{"schema":{"type":"string"},"name":"engineStatus","in":"query","required":false}],"tags":["Engines"]}}}}
```


# Templates

***

## Upload a template

> Upload a template to the server

```json
{"openapi":"3.1.1","info":{"title":"ByteNite developers API","version":"0.1"},"tags":[],"servers":[{"url":"https://api.bytenite.com/v1/dev"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"commonGenericResponse":{"type":"object","properties":{"ok":{"type":"boolean","description":"True if the request was successful."},"requestId":{"type":"string","description":"Internal request identifier for tracing or support."},"message":{"type":"string","description":"Additional message providing status or context."},"error":{"$ref":"#/components/schemas/commonError","description":"Optional error information if the request failed."}}},"commonError":{"type":"object","properties":{"code":{"type":"integer","format":"int64","description":"Error code if the request failed."},"message":{"type":"string","description":"Short description of the error if occurred."},"description":{"type":"string","description":"Full detailed explanation of the error if applicable."}}},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}},"protobufAny":{"type":"object","properties":{"@type":{"type":"string"}},"additionalProperties":{}},"jobJobTemplate":{"type":"object","properties":{"id":{"type":"string","title":"Unique ID for this Job Template (primary key)"},"createdAt":{"type":"string","format":"date-time","title":"Creation time of the job template"},"updatedAt":{"type":"string","format":"date-time","title":"Timestamp when the job template was last updated"},"isPublic":{"type":"boolean","title":"Indicates if this Job Template is public"},"partitioner":{"type":"string","title":"How data is partitioned"},"assembler":{"type":"string","title":"How data is assembled/merged"},"dataSource":{"$ref":"#/components/schemas/data_sourceDataSource","title":"Input data source"},"dataDestination":{"$ref":"#/components/schemas/data_sourceDataSource","title":"Output data destination"},"params":{"$ref":"#/components/schemas/jobParams","title":"Parameters for the job"},"config":{"$ref":"#/components/schemas/jobJobConfig","title":"Configuration for the job"},"userName":{"type":"string","description":"User name of the template owner."},"description":{"type":"string","title":"Description of this Job Template"},"app":{"type":"string","title":"The application associated with this Job Template"},"owner":{"type":"string","title":"Owner of this Job Template (primary key)"}},"description":"The templates specific to each app are stored in this table."},"data_sourceDataSource":{"type":"object","properties":{"dataSourceDescriptor":{"type":"string","description":"Data source selector."},"params":{"$ref":"#/components/schemas/protobufAny","description":"Data source parameters."}},"description":"The data source object specifying configurations for inputs and outputs. Please refer to the dedicated guide for detailed instructions."},"jobParams":{"type":"object","properties":{"partitioner":{"type":"object"},"app":{"type":"object"},"assembler":{"type":"object"}},"title":"Parameters holds the parameters for the job"},"jobJobConfig":{"type":"object","properties":{"taskTimeout":{"type":"integer","format":"int64","title":"task timeout in seconds"},"jobTimeout":{"type":"integer","format":"int64","title":"job timeout in seconds"},"isTestJob":{"type":"boolean","title":"'true' if this job is a test job"},"maxTaskRetries":{"type":"integer","format":"int64","title":"Maximum number of retries for each task in the job"}}}}},"paths":{"/templates":{"post":{"summary":"Upload a template","description":"Upload a template to the server","operationId":"Developer_UploadTemplate","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/commonGenericResponse"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/commonGenericResponse"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"tags":["templates"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/jobJobTemplate"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/jobJobTemplate"}}},"description":"The templates specific to each app are stored in this table.","required":true}}}}}
```

***

## Get a template

> Get a template by id

```json
{"openapi":"3.1.1","info":{"title":"ByteNite developers API","version":"0.1"},"tags":[],"servers":[{"url":"https://api.bytenite.com/v1/dev"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"jobJobTemplate":{"type":"object","properties":{"id":{"type":"string","title":"Unique ID for this Job Template (primary key)"},"createdAt":{"type":"string","format":"date-time","title":"Creation time of the job template"},"updatedAt":{"type":"string","format":"date-time","title":"Timestamp when the job template was last updated"},"isPublic":{"type":"boolean","title":"Indicates if this Job Template is public"},"partitioner":{"type":"string","title":"How data is partitioned"},"assembler":{"type":"string","title":"How data is assembled/merged"},"dataSource":{"$ref":"#/components/schemas/data_sourceDataSource","title":"Input data source"},"dataDestination":{"$ref":"#/components/schemas/data_sourceDataSource","title":"Output data destination"},"params":{"$ref":"#/components/schemas/jobParams","title":"Parameters for the job"},"config":{"$ref":"#/components/schemas/jobJobConfig","title":"Configuration for the job"},"userName":{"type":"string","description":"User name of the template owner."},"description":{"type":"string","title":"Description of this Job Template"},"app":{"type":"string","title":"The application associated with this Job Template"},"owner":{"type":"string","title":"Owner of this Job Template (primary key)"}},"description":"The templates specific to each app are stored in this table."},"data_sourceDataSource":{"type":"object","properties":{"dataSourceDescriptor":{"type":"string","description":"Data source selector."},"params":{"$ref":"#/components/schemas/protobufAny","description":"Data source parameters."}},"description":"The data source object specifying configurations for inputs and outputs. Please refer to the dedicated guide for detailed instructions."},"protobufAny":{"type":"object","properties":{"@type":{"type":"string"}},"additionalProperties":{}},"jobParams":{"type":"object","properties":{"partitioner":{"type":"object"},"app":{"type":"object"},"assembler":{"type":"object"}},"title":"Parameters holds the parameters for the job"},"jobJobConfig":{"type":"object","properties":{"taskTimeout":{"type":"integer","format":"int64","title":"task timeout in seconds"},"jobTimeout":{"type":"integer","format":"int64","title":"job timeout in seconds"},"isTestJob":{"type":"boolean","title":"'true' if this job is a test job"},"maxTaskRetries":{"type":"integer","format":"int64","title":"Maximum number of retries for each task in the job"}}},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}}}},"paths":{"/templates/{id}":{"get":{"summary":"Get a template","description":"Get a template by id","operationId":"Developer_GetTemplateById","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/jobJobTemplate"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/jobJobTemplate"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"parameters":[{"schema":{"type":"string"},"name":"id","in":"path","required":true}],"tags":["templates"]}}}}
```

***

## Get templates

> List all templates created by the user

```json
{"openapi":"3.1.1","info":{"title":"ByteNite developers API","version":"0.1"},"tags":[],"servers":[{"url":"https://api.bytenite.com/v1/dev"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"developerTemplateListResponse":{"type":"object","properties":{"templates":{"type":"array","items":{"$ref":"#/components/schemas/jobJobTemplate"}},"pagination":{"$ref":"#/components/schemas/commonPaginatedResponse"}}},"jobJobTemplate":{"type":"object","properties":{"id":{"type":"string","title":"Unique ID for this Job Template (primary key)"},"createdAt":{"type":"string","format":"date-time","title":"Creation time of the job template"},"updatedAt":{"type":"string","format":"date-time","title":"Timestamp when the job template was last updated"},"isPublic":{"type":"boolean","title":"Indicates if this Job Template is public"},"partitioner":{"type":"string","title":"How data is partitioned"},"assembler":{"type":"string","title":"How data is assembled/merged"},"dataSource":{"$ref":"#/components/schemas/data_sourceDataSource","title":"Input data source"},"dataDestination":{"$ref":"#/components/schemas/data_sourceDataSource","title":"Output data destination"},"params":{"$ref":"#/components/schemas/jobParams","title":"Parameters for the job"},"config":{"$ref":"#/components/schemas/jobJobConfig","title":"Configuration for the job"},"userName":{"type":"string","description":"User name of the template owner."},"description":{"type":"string","title":"Description of this Job Template"},"app":{"type":"string","title":"The application associated with this Job Template"},"owner":{"type":"string","title":"Owner of this Job Template (primary key)"}},"description":"The templates specific to each app are stored in this table."},"data_sourceDataSource":{"type":"object","properties":{"dataSourceDescriptor":{"type":"string","description":"Data source selector."},"params":{"$ref":"#/components/schemas/protobufAny","description":"Data source parameters."}},"description":"The data source object specifying configurations for inputs and outputs. Please refer to the dedicated guide for detailed instructions."},"protobufAny":{"type":"object","properties":{"@type":{"type":"string"}},"additionalProperties":{}},"jobParams":{"type":"object","properties":{"partitioner":{"type":"object"},"app":{"type":"object"},"assembler":{"type":"object"}},"title":"Parameters holds the parameters for the job"},"jobJobConfig":{"type":"object","properties":{"taskTimeout":{"type":"integer","format":"int64","title":"task timeout in seconds"},"jobTimeout":{"type":"integer","format":"int64","title":"job timeout in seconds"},"isTestJob":{"type":"boolean","title":"'true' if this job is a test job"},"maxTaskRetries":{"type":"integer","format":"int64","title":"Maximum number of retries for each task in the job"}}},"commonPaginatedResponse":{"type":"object","properties":{"total":{"type":"integer","format":"int64","description":"The total number of transactions available."},"offset":{"type":"integer","format":"int64","description":"The starting position of the current page of results, starting from 0."},"hasPrevious":{"type":"boolean","description":"A boolean value (True/False) indicating whether there's a previous page of results. False if the current page is the first page."},"hasNext":{"type":"boolean","description":"A boolean value indicating whether there's a next page of results."}},"description":"This section provides information about how the results are divided into pages."},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}}}},"paths":{"/templates":{"get":{"summary":"Get templates","description":"List all templates created by the user","operationId":"Developer_GetTemplates","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/developerTemplateListResponse"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/developerTemplateListResponse"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"parameters":[{"schema":{"type":"string"},"name":"orderBy","description":"Field name to sort apps by (e.g., createdAt).","in":"query","required":false},{"schema":{"type":"integer","format":"int64"},"name":"pagination.limit","description":"Number of rows to return per page.","in":"query","required":false},{"schema":{"type":"integer","format":"int64"},"name":"pagination.offset","description":"Number of rows to skip before starting to collect the result set.","in":"query","required":false},{"schema":{"type":"boolean"},"name":"isPublic","description":"Filter public templates only","in":"query","required":false}],"tags":["templates"]}}}}
```


# Wallet API

## About

* Base URL: `https://api.bytenite.com/v1/wallet`
* Version: `v1`
* Swagger Docs: <https://api.bytenite.com/v1/wallet/docs/>
* Specification: <https://api.bytenite.com/v1/wallet/docs/swagger.json>


# Balance

***

## Get wallet balance

> Get wallet balance for current user

```json
{"openapi":"3.1.1","info":{"title":"ByteNite wallet API","version":"0.1"},"tags":[{"name":"Wallet"}],"servers":[{"url":"https://api.bytenite.com/v1/wallet"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"walletGetBalanceResponse":{"type":"object","properties":{"accountId":{"type":"string","description":"A unique identifier associated with your ByteNite wallet account, separate from your userId."},"totalBalance":{"type":"number","format":"double","description":"This represents the total amount of credits or funds available in your ByteNite wallet. This is the overall balance, including any funds that might be reserved or locked."},"availableBalance":{"type":"number","format":"double","description":"This is the portion of your total balance that is readily available for use. It excludes any funds that might be held for pending transactions or subscriptions."},"amountDue":{"type":"number","format":"double","description":"This represents the dollar value equivalent to the pending ByteChips due at the end of the billing period."}}},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}},"protobufAny":{"type":"object","properties":{"@type":{"type":"string"}},"additionalProperties":{}}}},"paths":{"/balance":{"get":{"summary":"Get wallet balance","description":"Get wallet balance for current user","operationId":"Wallet_GetBalance","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/walletGetBalanceResponse"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/walletGetBalanceResponse"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"tags":["Wallet"]}}}}
```


# Transactions

***

## Get transaction history

> Get paginated list of transactions

```json
{"openapi":"3.1.1","info":{"title":"ByteNite wallet API","version":"0.1"},"tags":[{"name":"Wallet"}],"servers":[{"url":"https://api.bytenite.com/v1/wallet"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"walletTransactionHistoryResponse":{"type":"object","properties":{"pagination":{"$ref":"#/components/schemas/commonPaginatedResponse"},"data":{"type":"array","items":{"$ref":"#/components/schemas/bytenitewalletTransaction"}}}},"commonPaginatedResponse":{"type":"object","properties":{"total":{"type":"integer","format":"int64","description":"The total number of transactions available."},"offset":{"type":"integer","format":"int64","description":"The starting position of the current page of results, starting from 0."},"hasPrevious":{"type":"boolean","description":"A boolean value (True/False) indicating whether there's a previous page of results. False if the current page is the first page."},"hasNext":{"type":"boolean","description":"A boolean value indicating whether there's a next page of results."}},"description":"This section provides information about how the results are divided into pages."},"bytenitewalletTransaction":{"type":"object","properties":{"id":{"type":"string","description":"A unique identifier for this specific transaction."},"createdAt":{"type":"string","format":"date-time","description":"The date and time when the transaction was created."},"accountFrom":{"type":"string","description":"The identifier of the account the transaction originated from."},"accountTo":{"type":"string","description":"The identifier of the account the transaction was sent to (e.g., stripe-main, our payment processor)."},"amount":{"type":"number","format":"double","description":"The cost in ByteChips of the transaction."},"transactionType":{"type":"string","description":"A classification of the transaction type."},"relatedEntity":{"$ref":"#/components/schemas/commonEntity","description":"This section provides information about any entity connected to the transaction."},"notes":{"type":"string","description":"Any additional notes or comments related to the transaction."},"transactionData":{"$ref":"#/components/schemas/protobufAny","description":"Extra data associated with the transaction."},"hash":{"type":"string","description":"A cryptographic hash of the transaction for security and verification."},"relatedEntityData":{"$ref":"#/components/schemas/walletRelatedEntityData","description":"Provides more detailed data about the related entity."},"description":{"type":"string","description":"A human-readable description of the transaction."},"balance":{"type":"number","format":"double","description":"The remaining balance after the transaction."}}},"commonEntity":{"type":"object","properties":{"type":{"type":"string","description":"The type of the entity. This is a string that represents the type of the entity, such as \"user\", \"device\", etc."},"id":{"type":"string","description":"The unique identifier for the entity. This is a string that represents the unique identifier of the entity."},"name":{"type":"string","description":"The name of the related entity."}},"description":"This message represents a generic entity with a type and an ID. It can be used to represent different types of entities in the system."},"protobufAny":{"type":"object","properties":{"@type":{"type":"string"}},"additionalProperties":{}},"walletRelatedEntityData":{"type":"object","properties":{"type":{"type":"string","description":"The type of related entity."},"id":{"type":"string","description":"The unique identifier for the related entity."},"name":{"type":"string","description":"The name of the related entity."},"jobName":{"type":"string","description":"For type = payment, The name of the job associated with the payment."},"jobId":{"type":"string","description":"The ID of the job associated with the payment."},"description":{"type":"string","description":"For type = topup, A description of the top-up transaction."},"currency":{"type":"string","description":"The currency used in the top-up."},"currencyAmount":{"type":"string","format":"int64","description":"The amount in the specified currency."},"exchangeRate":{"type":"number","format":"double","description":"The exchange rate applied to the transaction."},"couponCode":{"type":"string","description":"For type = coupon, The coupon code applied to the transaction."},"jobTemplate":{"type":"string","description":"The job template id associated with the corresponding job."}}},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}}}},"paths":{"/transactions":{"get":{"summary":"Get transaction history","description":"Get paginated list of transactions","operationId":"Wallet_GetTransactionList","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/walletTransactionHistoryResponse"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/walletTransactionHistoryResponse"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"parameters":[{"schema":{"type":"integer","format":"int64"},"name":"pagination.limit","description":"Number of rows to return per page.","in":"query","required":false},{"schema":{"type":"integer","format":"int64"},"name":"pagination.offset","description":"Number of rows to skip before starting to collect the result set.","in":"query","required":false},{"schema":{"type":"string"},"name":"orderBy","in":"query","required":false}],"tags":["Wallet"]}}}}
```

***

## Get transaction history with filters

> post paginated list of transactions with filters

```json
{"openapi":"3.1.1","info":{"title":"ByteNite wallet API","version":"0.1"},"tags":[{"name":"Wallet"}],"servers":[{"url":"https://api.bytenite.com/v1/wallet"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"walletTransactionHistoryResponse":{"type":"object","properties":{"pagination":{"$ref":"#/components/schemas/commonPaginatedResponse"},"data":{"type":"array","items":{"$ref":"#/components/schemas/bytenitewalletTransaction"}}}},"commonPaginatedResponse":{"type":"object","properties":{"total":{"type":"integer","format":"int64","description":"The total number of transactions available."},"offset":{"type":"integer","format":"int64","description":"The starting position of the current page of results, starting from 0."},"hasPrevious":{"type":"boolean","description":"A boolean value (True/False) indicating whether there's a previous page of results. False if the current page is the first page."},"hasNext":{"type":"boolean","description":"A boolean value indicating whether there's a next page of results."}},"description":"This section provides information about how the results are divided into pages."},"bytenitewalletTransaction":{"type":"object","properties":{"id":{"type":"string","description":"A unique identifier for this specific transaction."},"createdAt":{"type":"string","format":"date-time","description":"The date and time when the transaction was created."},"accountFrom":{"type":"string","description":"The identifier of the account the transaction originated from."},"accountTo":{"type":"string","description":"The identifier of the account the transaction was sent to (e.g., stripe-main, our payment processor)."},"amount":{"type":"number","format":"double","description":"The cost in ByteChips of the transaction."},"transactionType":{"type":"string","description":"A classification of the transaction type."},"relatedEntity":{"$ref":"#/components/schemas/commonEntity","description":"This section provides information about any entity connected to the transaction."},"notes":{"type":"string","description":"Any additional notes or comments related to the transaction."},"transactionData":{"$ref":"#/components/schemas/protobufAny","description":"Extra data associated with the transaction."},"hash":{"type":"string","description":"A cryptographic hash of the transaction for security and verification."},"relatedEntityData":{"$ref":"#/components/schemas/walletRelatedEntityData","description":"Provides more detailed data about the related entity."},"description":{"type":"string","description":"A human-readable description of the transaction."},"balance":{"type":"number","format":"double","description":"The remaining balance after the transaction."}}},"commonEntity":{"type":"object","properties":{"type":{"type":"string","description":"The type of the entity. This is a string that represents the type of the entity, such as \"user\", \"device\", etc."},"id":{"type":"string","description":"The unique identifier for the entity. This is a string that represents the unique identifier of the entity."},"name":{"type":"string","description":"The name of the related entity."}},"description":"This message represents a generic entity with a type and an ID. It can be used to represent different types of entities in the system."},"protobufAny":{"type":"object","properties":{"@type":{"type":"string"}},"additionalProperties":{}},"walletRelatedEntityData":{"type":"object","properties":{"type":{"type":"string","description":"The type of related entity."},"id":{"type":"string","description":"The unique identifier for the related entity."},"name":{"type":"string","description":"The name of the related entity."},"jobName":{"type":"string","description":"For type = payment, The name of the job associated with the payment."},"jobId":{"type":"string","description":"The ID of the job associated with the payment."},"description":{"type":"string","description":"For type = topup, A description of the top-up transaction."},"currency":{"type":"string","description":"The currency used in the top-up."},"currencyAmount":{"type":"string","format":"int64","description":"The amount in the specified currency."},"exchangeRate":{"type":"number","format":"double","description":"The exchange rate applied to the transaction."},"couponCode":{"type":"string","description":"For type = coupon, The coupon code applied to the transaction."},"jobTemplate":{"type":"string","description":"The job template id associated with the corresponding job."}}},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}},"wallet_apiGetAllTransactionsRequest":{"type":"object","properties":{"pagination":{"$ref":"#/components/schemas/commonLimitOffsetPagination"},"filters":{"type":"array","items":{"$ref":"#/components/schemas/commonFilter"}},"orderBy":{"type":"string"}}},"commonLimitOffsetPagination":{"type":"object","properties":{"limit":{"type":"integer","format":"int64","description":"Number of rows to return per page."},"offset":{"type":"integer","format":"int64","description":"Number of rows to skip before starting to collect the result set."}}},"commonFilter":{"type":"object","properties":{"field":{"type":"string","description":"The field to apply the filter on"},"condition":{"$ref":"#/components/schemas/commonFilterCondition","description":"The condition to apply"},"value":{"type":"object","$ref":"#/components/schemas/protobufAny","description":"The value to filter on. Can be any type."}}},"commonFilterCondition":{"type":"string","enum":["FILTER_CONDITION_EQ","FILTER_CONDITION_NEQ","FILTER_CONDITION_GT","FILTER_CONDITION_GTE","FILTER_CONDITION_LT","FILTER_CONDITION_LTE","FILTER_CONDITION_ARRAY_CONTAINS","FILTER_CONDITION_ARRAY_CONTAINS_ANY","FILTER_CONDITION_IN","FILTER_CONDITION_NOT_IN","FILTER_CONDITION_LIKE"],"default":"FILTER_CONDITION_EQ"}}},"paths":{"/transactions/filter":{"post":{"summary":"Get transaction history with filters","description":"post paginated list of transactions with filters","operationId":"Wallet_PostTransactionListFilter","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/walletTransactionHistoryResponse"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/walletTransactionHistoryResponse"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"tags":["Wallet"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/wallet_apiGetAllTransactionsRequest"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/wallet_apiGetAllTransactionsRequest"}}},"required":true}}}}}
```

***

## Get transaction history as CSV

> Get CSV of all transactions

```json
{"openapi":"3.1.1","info":{"title":"ByteNite wallet API","version":"0.1"},"tags":[{"name":"Wallet"}],"servers":[{"url":"https://api.bytenite.com/v1/wallet"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"walletTransactionHistoryCsvResponse":{"type":"object","properties":{"csv":{"type":"string"}}},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}},"protobufAny":{"type":"object","properties":{"@type":{"type":"string"}},"additionalProperties":{}}}},"paths":{"/transactions/csv":{"get":{"summary":"Get transaction history as CSV","description":"Get CSV of all transactions","operationId":"Wallet_GetTransactionsCsv","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/walletTransactionHistoryCsvResponse"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/walletTransactionHistoryCsvResponse"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"tags":["Wallet"]}}}}
```


# Exchange Rate

***

## Get exchange rate in ByteChips for a currency

> Convert amount from currency to ByteChips

```json
{"openapi":"3.1.1","info":{"title":"ByteNite wallet API","version":"0.1"},"tags":[{"name":"Wallet"}],"servers":[{"url":"https://api.bytenite.com/v1/wallet"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"walletExchangeRateResponse":{"type":"object","properties":{"currency":{"type":"string"},"currencyAmount":{"type":"number","format":"double"},"exchangeRate":{"type":"number","format":"double"},"amount":{"type":"number","format":"double"}},"title":"Response messages"},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}},"protobufAny":{"type":"object","properties":{"@type":{"type":"string"}},"additionalProperties":{}}}},"paths":{"/exchange_rate":{"get":{"summary":"Get exchange rate in ByteChips for a currency","description":"Convert amount from currency to ByteChips","operationId":"Wallet_GetExchangeRate","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/walletExchangeRateResponse"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/walletExchangeRateResponse"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"parameters":[{"schema":{"type":"string"},"name":"currency","in":"query","required":false},{"schema":{"type":"number","format":"double"},"name":"currencyAmount","in":"query","required":false},{"schema":{"type":"number","format":"double"},"name":"amount","in":"query","required":false}],"tags":["Wallet"]}}}}
```


# Redeem Coupon

***

## Redeem promo code

> Redeem a promo code

```json
{"openapi":"3.1.1","info":{"title":"ByteNite wallet API","version":"0.1"},"tags":[{"name":"Wallet"}],"servers":[{"url":"https://api.bytenite.com/v1/wallet"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","description":"Your ByteNite access token","name":"Authorization","in":"header"}},"schemas":{"wallet_apiRedeemCouponResponse":{"type":"object","properties":{"id":{"type":"string"},"code":{"type":"string"},"amount":{"type":"string","format":"int64"}}},"rpcStatus":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"array","items":{"$ref":"#/components/schemas/protobufAny"}}}},"protobufAny":{"type":"object","properties":{"@type":{"type":"string"}},"additionalProperties":{}},"bytenitewallet_apiRedeemCouponRequest":{"type":"object","properties":{"couponCode":{"type":"string","title":"The coupon code to redeem"}}}}},"paths":{"/redeem_coupon":{"post":{"summary":"Redeem promo code","description":"Redeem a promo code","operationId":"Wallet_RedeemCoupon","responses":{"200":{"description":"A successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/wallet_apiRedeemCouponResponse"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/wallet_apiRedeemCouponResponse"}}}},"400":{"description":"Returned when the users sends a malformed request.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"401":{"description":"Returned when the user is not authenticated.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"403":{"description":"Returned when the user does not have permission to access the resource.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"404":{"description":"Returned when the resource does not exist.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"500":{"description":"Returned when an error on the server occurred.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"503":{"description":"Returned when the resource is temporarily unavailable.","content":{"application/json":{"schema":{}},"application/x-protobuf":{"schema":{}}}},"default":{"description":"An unexpected error response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/rpcStatus"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/rpcStatus"}}}}},"tags":["Wallet"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/bytenitewallet_apiRedeemCouponRequest"}},"application/x-protobuf":{"schema":{"$ref":"#/components/schemas/bytenitewallet_apiRedeemCouponRequest"}}},"required":true}}}}}
```


# ByteNite Computing Platform

## Introduction

The ByteNite Computing Platform GUI is a web interface that enables users to manage and monitor distributed computing jobs on ByteNite, allowing users to launch, track, and control their workloads.

***

## Job Management

### **Create New Jobs**

In order to create a new job, from the **Jobs** page, click the "New Job" button at the top. Here, you'll have two options:

* **Start from Scratch** - you'll manually configure all parameters, including:
  * **Job Details** - job name and description
  * **App Details** - deployed app references for your partitioner, app, and assembler (you may specify versioning to test specific versions of your app, partitioner and assembler, by default the most recent version of each will be used)
  * **Setup** - data source and destination types, parameter configs for your app references, and timeout and retry configs.

{% embed url="<https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC4oKwqyUo55Lw35MjazY%2Fuploads%2F1IaDEXu75FPMHEGCjcRM%2FMOV%20to%20MP4%20test.mp4?alt=media&token=7183182b-d516-470e-9c7e-ac83b0915a8b>" %}

* **Use a Template -** Alternatively, you can pick an existing template from your **Templates** table and click on it to create a new job. This will give you the option to create a job to either run later or immediately, using the preconfigured data source and destination, parameters, and configs you defined in your selected template.

<figure><img src="https://1271894904-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC4oKwqyUo55Lw35MjazY%2Fuploads%2F8TR6rdueyLEPo1FBWNKr%2FScreenshot%202025-10-22%20at%205.09.06%E2%80%AFPM.png?alt=media&amp;token=271b246f-6df0-4d72-b876-662d5b0b8a55" alt=""><figcaption></figcaption></figure>

### **Launch Jobs**

You can launch a new job immediately after configuration in **Start from Scratch** by clicking **Create & Run Job**, as shown in the demo video in the section above. Alternatively, clicking **Create Job** allows you to save the job as a draft. You can later execute it using job actions from the Jobs page or the job overview by selecting **Run Job**.

<figure><img src="https://1271894904-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC4oKwqyUo55Lw35MjazY%2Fuploads%2FjJKXOOCuOT4Ui269XeEp%2FScreenshot%202025-10-22%20at%206.49.42%E2%80%AFPM.png?alt=media&amp;token=f15d9fb0-8385-414e-aea2-f86d4a123657" alt=""><figcaption></figcaption></figure>

<figure><img src="https://1271894904-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC4oKwqyUo55Lw35MjazY%2Fuploads%2F2eoeSmNOEPZ74s8m367x%2FScreenshot%202025-10-22%20at%206.50.00%E2%80%AFPM.png?alt=media&amp;token=a1f9a199-f276-44b5-ab03-bef3919d43fd" alt=""><figcaption></figcaption></figure>

You can additionally launch a job from a pre-saved template using **Use a Template**. Simply select the row of which template you would like to use and confirm that it is configured correctly. For more information on how to properly define your jobs, see the parameters in the **Start from Scratch** section above.&#x20;

### **Delete Jobs**

Remove jobs that are no longer needed, with confirmation prompts to prevent accidental deletion. This can be conducted through the Jobs page or through the red button on the top right of the specific job's Overview page.

<figure><img src="https://1271894904-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC4oKwqyUo55Lw35MjazY%2Fuploads%2FlaywW6o2BdGumxxSVyOF%2FScreenshot%202025-10-22%20at%207.43.57%E2%80%AFPM.png?alt=media&amp;token=b163c924-a214-4b55-b95d-af32b449bfb0" alt=""><figcaption></figcaption></figure>

### **Job Logging & Monitoring**

View real-time statuses such as *Running, Complete, and Failed*, along with progress bars for each job on the Jobs page. More detailed, time-stamped task status tracking is available on the Job's Overview page.&#x20;

<figure><img src="https://1271894904-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC4oKwqyUo55Lw35MjazY%2Fuploads%2FhI39LeHqrkG6jgYfPFcH%2Fimage.png?alt=media&amp;token=32278c32-6494-481d-8558-42148e4a70b9" alt=""><figcaption></figcaption></figure>

Additionally, the Job Overview page includes a Logs section, which contains logs from the partitioner, app, and assembler processes. While the logs are presented comprehensively, they can be filtered for troubleshooting by categories: error, warning, info, debug, and unknown. These logs are also queryable and downloadable.

<figure><img src="https://1271894904-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC4oKwqyUo55Lw35MjazY%2Fuploads%2FZzFbQ91cWIc8dh3i7rTJ%2Fimage.png?alt=media&amp;token=d24e951d-2cb2-4e73-b172-6d0ad1bfcf9e" alt=""><figcaption></figcaption></figure>

***

## Task Management

Tasks are the individual units of work that make up a job. Each job may consist of multiple tasks, which can be executed in parallel or sequence, depending on the workload.

#### **View Task Breakdown & Progress**

Inspect the list of tasks associated with a job, breaking down their time-stamped state (*Scheduled, Assigned, Received, Running, Completed*) and price. Deeper insights are available at the individual task level, including the container stats, network stats, and device info.

<figure><img src="https://1271894904-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC4oKwqyUo55Lw35MjazY%2Fuploads%2Fc6Kf2FssBIe8iVg6AyOb%2Fimage.png?alt=media&amp;token=88555e5f-cf8b-4b73-8885-3a5539f3213c" alt=""><figcaption></figcaption></figure>

#### Task Logs

Access detailed logs for each task by clicking into that specific **Task ID** to diagnose issues at a granular level.

<figure><img src="https://1271894904-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC4oKwqyUo55Lw35MjazY%2Fuploads%2FpXSIJM2NZxxJGiAxq6Jn%2Fimage.png?alt=media&amp;token=971684a9-b514-4a2a-81d6-832c22d2d6b2" alt=""><figcaption></figcaption></figure>

***

## Templates Management

The **Templates** page allows users to observe and reuse submitted job templates for common or recurring workloads. Templates help ensure consistency, reduce setup time, and minimize errors when launching similar jobs. For info on using templates for job setup, view **Use a Template** in the [Create New Job](#create-new-jobs) section above.

If you want to delete a template, simply select the ellipses at the end of the row of the desired template and click **Delete**.&#x20;

<figure><img src="https://1271894904-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC4oKwqyUo55Lw35MjazY%2Fuploads%2FMJQOtGPMocBeZkRRuQrG%2FScreenshot%202025-10-22%20at%208.03.42%E2%80%AFPM.png?alt=media&amp;token=8f4a2f61-61a5-4472-9b74-86b12f8c16a7" alt=""><figcaption></figcaption></figure>

***

## Security

The Security section houses both the pages for API Key and Secret Management:

### API Keys

The API Keys page allows users to securely generate and manage their personal API keys. These keys are essential credentials required to access the platform’s APIs, enabling programmatic interaction with ByteNite’s distributed computing services.

On this page, users can:

* **Create New API Keys:** Generate unique API keys for use in scripts, applications, or integrations that need to interact with the ByteNite platform outside of the web interface.
* **View and Copy Existing Keys:** Easily view your active API keys and copy them for use in your development environment or automation tools.
* **Revoke Keys:** Revoke keys that are no longer needed.

<figure><img src="https://1271894904-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC4oKwqyUo55Lw35MjazY%2Fuploads%2FNeDyMvIp2QBTfV0l756V%2FScreenshot%202025-10-22%20at%208.46.03%E2%80%AFPM.png?alt=media&amp;token=292cc371-190b-440b-9de4-01a45b284326" alt=""><figcaption></figcaption></figure>

### Secrets

The Secrets page lets you manage credentials used by your apps and engines across your jobs. ByteNite currently supports secret types from AWS, GCP, and Storj. All that's needed from you prior to setting up your secret is your Access Key and your Secret Key from that respective platform.

Each secret is assigned a unique **Secret ID**, defined by you, which you can reference in your environment variable configuration to inject credentials at runtime—eliminating the need to hardcode sensitive values.

For step-by-step instructions on using Secret IDs in environment variables, see: [Environment Variable Injection](https://app.gitbook.com/o/hWTaF6n2ZDainV7RJ5Q9/s/C4oKwqyUo55Lw35MjazY/~/changes/47/create-with-bytenite/containers-and-environments#environment-variable-injection).

<figure><img src="https://1271894904-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC4oKwqyUo55Lw35MjazY%2Fuploads%2FbJvEgO8587r19H28LIkA%2FScreenshot%202025-10-22%20at%208.56.05%E2%80%AFPM.png?alt=media&amp;token=66c628b2-bd75-4635-9517-98e1d5dff0d8" alt=""><figcaption></figcaption></figure>

***

## Billing

The Billing page is where users manage their transactions. It includes several key sections:

#### **Usage Overview**&#x20;

This section displays ByteChip usage over a selected month. Users can adjust the view to focus on a specific month or template.

#### **Wallet Balance**&#x20;

Here, users can add ByteChips to their account via Top Up or Coupon Redemption. This section also allows users to view and copy their account ID, check both total and available balances, and see the amount due. Additionally, it includes a Customer Portal button for accessing the ByteNite Stripe integration.

#### **Wallet Transactions**&#x20;

This section lists all your transactions. It provides detailed information such as transaction type (Top Up, Coupon, Payment), description, costs in both ByteChips and USD, and the remaining balance.

<figure><img src="https://1271894904-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC4oKwqyUo55Lw35MjazY%2Fuploads%2F128aUK6EuO1tZ2wVXQAb%2Fimage.png?alt=media&amp;token=00ec7de2-563c-4452-a385-09ac915ede94" alt=""><figcaption></figcaption></figure>

***

## Contact Us

The Contact Us page provides a simple way for users to reach the ByteNite team with questions, issues, or feedback. To submit a query, just fill out the following fields:&#x20;

* **Email:** Enter your email address so we can get back to you.
* **Summary:** Provide a brief summary of your request or concern.
* **Description:** Use this field to describe your issue or feedback in detail.

Once submitted, our team will review your message and respond as soon as possible.

<figure><img src="https://1271894904-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC4oKwqyUo55Lw35MjazY%2Fuploads%2F2Vk079PXdAfEEzCM0gy2%2Fimage.png?alt=media&amp;token=7f4171d8-2e23-4639-a673-2d55409a3813" alt=""><figcaption></figcaption></figure>

***

## Documentation

The Documentation page will redirect you to [Introduction](/) page, where you can find detailed guides, feature overviews, and best practices for using the ByteNite Computing Platform.

***

## Developer CLI&#x20;

The Developer CLI page will take you directly to the [Developer CLI](/create-with-bytenite/bytenite-dev-cli) page, explaining setup instructions, usage examples, and advanced command references.

{% hint style="warning" %}
This page is **under construction**! Please come back later...
{% endhint %}


# Changelog

Track updates, improvements, and fixes across each release of the platform.

## Release Notes – October 6, 2025

**✨ New Features**

* Added support for secret type “other”, expanding secret management capabilities.
* Enabled automatic injection of secrets into apps and engines, allowing access through environment variables.

***

## Release Notes – September 19, 2025

**✨ New Features**

* Introduced entity delete APIs for streamlined data management.
* Added Server-Sent Events (SSE) for real-time task status updates in the backend.

**⚡ Improvements**

* Renamed secrets and dataSourceDescriptor references from S3 to AWS for consistency across services.

***

## Release Notes – September 12, 2025

**⚡ Improvements**

* Updated backend API routing from v1/customer/ → v1/computing/, preparing for the deprecation of older endpoints.
* Populated the username field for existing user records to improve identity consistency.

**🐞 Fixes**

* Resolved issues related to template and engine import operations.

**🗑️ Deprecations**

* Marked the /customer/stats endpoint as deprecated in favor of updated computing metrics APIs.

***

## Release Notes – September 3, 2025

**✨ New Features**

Implemented a shared cache directory on GCS for worker VMs, allowing apps to access cached data via predefined environment variables.

***

## Release Notes – August 29, 2025

**✨ New Features**

* Introduced APIs/CLI commands for publishing and unpublishing apps, engines, and templates
* Added public entity import functionality through both API and CLI commands
* Added new API endpoints for browsing and uploading cache
* Added support for username creation

**⚡ Improvements**

* Improved task assignment to ensure correct distribution across CPU and GPU devices

**🐞 Fixes**

* Fixed issues with validating data sources and destinations in templates

**🗑️ Deprecations**

* Removed support for stale tasks
* Deprecated job presets and schemas

***

## Release Notes – August 21, 2025

**✨ New Features**

* Added onboarding prompt displayed on first login to the computing UI platform

**⚡ Improvements**

* Restructured jobs and templates table
* Enabled job creation from either a template or from scratch


# Glossary

## A.

<details>

<summary><mark style="color:blue;"><strong>App</strong></mark></summary>

*A ByteNite App is a custom software program consisting of application scripts and configuration files, designed by the user to operate on the ByteNite platform. An app can integrate with a partitioner and an assembler to enhance its distributed processing capabilities.*&#x20;

</details>

<details>

<summary><mark style="color:blue;"><strong>Assembler</strong></mark></summary>

*An Assembler is a custom software program designed by the user to handle post-processing and fan-in operations on the ByteNite platform.*&#x20;

**Additional Info:**

* AKA: <mark style="color:blue;">**Assembling Engine**</mark>

**Related Guides:**

* [Assembling Engines](/create-with-bytenite/building-blocks/assembling-engines)
* [Building Blocks](/create-with-bytenite/building-blocks)

</details>

## B.

<details>

<summary><mark style="color:blue;"><strong>ByteChip</strong></mark></summary>

*ByteChip is the internal currency used within the ByteNite platform for measuring and trading computing services. It is the standard unit to evaluate computing throughput provided by task runners. One ByteChip is equivalent to the price of an hour of computation on a machine with 1 CPU core and 1 GiB of RAM.*

**Additional Info:**

* Abbreviation/ticker: <mark style="color:blue;">**BYC**</mark>
* Symbol: <img src="https://1271894904-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC4oKwqyUo55Lw35MjazY%2Fuploads%2FjapeRRAuPZo4y8Ir1ndj%2FByteChips-symbol-iconsize.png?alt=media&amp;token=a9c7d12e-afc3-4643-9abd-d3de26288128" alt="" data-size="line">
* ByteChips are **not** cryptocurrency

</details>

## P.

<details>

<summary><mark style="color:blue;"><strong>Partitioner</strong></mark></summary>

*A Partitioner is a custom software program designed by the user to handle pre-processing and fan-out operations on the ByteNite platform.*&#x20;

**Additional Info:**

* AKA: <mark style="color:blue;">**Partitioning Engine**</mark>

**Related Guides:**

* [Partitioning Engines](/create-with-bytenite/building-blocks/partitioning-engines)
* [Building Blocks](/create-with-bytenite/building-blocks)

</details>

## T.

<details>

<summary><mark style="color:blue;"><strong>Tag</strong></mark></summary>

*In ByteNite, a tag is a string used to identify a record by version. The tag format includes a required record name and an optional version in the format: `[name]@[major].[minor]` . The minor version is optional. Tag behavior follows these principles:*

* *`[name]@[major].[minor]`*

  *Retrieves the record matching the exact name, major version, and minor version.*
* *`[name]@[major]`*

  *Retrieves the record matching the exact name and major version, with the highest minor version.*
* *`[name]`*

  *Retrieves the record by name with the highest major and minor versions.*

</details>


