# Overview

Nebula Block documentation — serverless inference, GPU cloud, and S3-compatible object storage, with Canadian-hosted options.

Welcome to [Nebula Block](https://www.nebulablock.com/) — a Montreal-based AI cloud offering serverless inference, on-demand GPU compute, and S3-compatible object storage, with Canadian-hosted options for workloads that have data-residency requirements.

These docs cover everything from your first API call to the full REST reference.

## Start here

| If you want to…                           | Go to                                                         |
| ----------------------------------------- | ------------------------------------------------------------- |
| Make your first API call in a few minutes | [Quickstart](/getting-started/get-started/quickstart)         |
| Understand what Nebula Block offers       | [Products](/getting-started/get-started/products)             |
| See which models you can call             | [Model Catalog](/products/serverless-inference/model-catalog) |
| Know your rate limits                     | [Tiers and Rate Limits](/account/tiers-and-limits)            |
| Look up an endpoint                       | [API Reference](/api-reference/api-reference)                 |

## Core products

### Serverless Inference

Call state-of-the-art models — text, vision, image, video, embedding, and reranking — through a single OpenAI-compatible endpoint at `https://inference.nebulablock.com/v1`. No servers to provision, no models to load; point any OpenAI SDK at it and go.

→ [Serverless Inference](/products/serverless-inference) · [Model Catalog](/products/serverless-inference/model-catalog)

### GPU Cloud

Rent on-demand GPU and CPU instances by the hour, from single GPUs to multi-GPU nodes, deployed in minutes with your own SSH keys and firewall rules.

→ [GPU Cloud](/products/gpu-cloud)

### Object Storage

S3-compatible storage for datasets, checkpoints, and model outputs. Works with `s3cmd`, `boto3`, and the AWS SDKs you already use.

→ [Object Storage](/products/object-storage)

## Build with the API

Nebula Block exposes two APIs:

| API                                   | Base URL                               | Use it for                                                     |
| ------------------------------------- | -------------------------------------- | -------------------------------------------------------------- |
| **Inference API** (OpenAI-compatible) | `https://inference.nebulablock.com/v1` | Chat completions, vision, images, video, embeddings, reranking |
| **Platform API**                      | `https://api.nebulablock.com/api/v1`   | Instances, SSH keys, API keys, object storage, billing, teams  |

→ [API Reference](/api-reference/api-reference) · [Authentication](/api-reference/authentication)

## Manage your account

* [API Keys](/account/api-keys) — create and rotate keys
* [Tiers and Rate Limits](/account/tiers-and-limits) — what your tier unlocks
* [Teams](/account/teams) — shared billing, roles, and team API keys
* [Referral Program](/account/referral) — earn commission on referred spend

## Get help

* [FAQ](/resources/faq) · [Glossary](/resources/glossary)
* [Contact Us](/resources/contact)
* [Legal](/resources/legal)


# Getting Started

Start here: create an account, get an API key, and make your first call to Nebula Block.

New to Nebula Block? Work through these in order.

|                                                           |                                                              |
| --------------------------------------------------------- | ------------------------------------------------------------ |
| [**Quickstart**](/getting-started/get-started/quickstart) | Create an account, get a key, make your first inference call |
| [**Account**](/getting-started/get-started/account)       | Sign-up, activation, profile, and password management        |
| [**Billing**](/getting-started/get-started/billing)       | Credit, payment methods, auto-pay, and invoices              |
| [**Products**](/getting-started/get-started/products)     | What Nebula Block offers and which tier each product needs   |

Once you are set up, the [Model Catalog](/products/serverless-inference/model-catalog) lists everything you can call, and the [API Reference](/api-reference/api-reference) documents every endpoint.


# Quickstart

Create an account, add credit, get an API key, and make your first inference call in about five minutes.

Make your first inference call in about five minutes.

## 1. Create an account

[Sign up](https://console.nebulablock.com/register) and confirm your email address. See [Account](/getting-started/get-started/account) for details on activation, profile settings, and password resets.

## 2. Add credit

Serverless inference is pay-as-you-go, and **Tier 1 (free) accounts have a daily request cap of 0 on most models**. A $5 deposit moves you to Tier 2 and opens up the catalog; $10 also unlocks GPU instances.

Add credit under [Billing](https://console.nebulablock.com/billing) in the console. See [Tiers and Rate Limits](/account/tiers-and-limits) for exactly what each tier unlocks.

## 3. Create an API key

Go to [API Keys](https://console.nebulablock.com/apiKeys) in the console and create a key, then copy it. You can reveal and copy it again later from the same page, but treat it like a password all the same.

```bash
export NEBULA_API_KEY="sk-..."
```

See [API Keys](/account/api-keys) for rotation and team keys.

## 4. Make your first call

The Inference API is OpenAI-compatible, so any OpenAI SDK works by changing the base URL.

### Using cURL

```bash
curl https://inference.nebulablock.com/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $NEBULA_API_KEY" \
  -d '{
    "model": "deepseek-ai/DeepSeek-V3.2",
    "messages": [{"role": "user", "content": "Explain what an inference endpoint is, in two sentences."}]
  }'
```

### Using Python

```python
import os

from openai import OpenAI

client = OpenAI(
    base_url="https://inference.nebulablock.com/v1",
    api_key=os.environ["NEBULA_API_KEY"],
)

response = client.chat.completions.create(
    model="deepseek-ai/DeepSeek-V3.2",
    messages=[{"role": "user", "content": "Explain what an inference endpoint is, in two sentences."}],
)
print(response.choices[0].message.content)
```

### Using JavaScript

```javascript
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://inference.nebulablock.com/v1",
  apiKey: process.env.NEBULA_API_KEY,
});

const response = await client.chat.completions.create({
  model: "deepseek-ai/DeepSeek-V3.2",
  messages: [{ role: "user", content: "Explain what an inference endpoint is, in two sentences." }],
});
console.log(response.choices[0].message.content);
```

Swap `model` for any ID from the [Model Catalog](/products/serverless-inference/model-catalog).

## Where to go next

| Goal                                       | Guide                                                                                                                                     |
| ------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------- |
| Stream responses, use tools, tune sampling | [Text Generation](/products/serverless-inference/text-generation)                                                                         |
| Send images to a model                     | [Vision](/products/serverless-inference/vision)                                                                                           |
| Generate images or video                   | [Image Generation](/products/serverless-inference/image-generation) · [Video Generation](/products/serverless-inference/video-generation) |
| Build RAG                                  | [Embeddings](/products/serverless-inference/embeddings) · [Reranking](/products/serverless-inference/reranking)                           |
| Rent a GPU                                 | [GPU Cloud Quickstart](/products/gpu-cloud/quickstart)                                                                                    |
| Store datasets                             | [Object Storage Quickstart](/products/object-storage/quickstart)                                                                          |

## See also

* [Products](/getting-started/get-started/products)
* [API Reference](/api-reference/api-reference)
* [FAQ](/resources/faq)


# Account

Create and activate a Nebula Block account, update your profile, reset your password, and delete an account.

## Create an Account

Sign up on the [Nebula Block website](https://nebulablock.com/) to create an account by clicking on [Sign up](https://console.nebulablock.com/register) in the top right corner of your screen and sign up with either email + password or through Google.

## Activate Account

Once you create an account, you need to activate it before you're able to sign in. An activation email will be sent to your account so make sure to activate it. If needed, you can resend the activation email by logging in, which will refer you to a page to resend the activation email.

## Updating Account Information

It is recommended once you create and activate your account to fill out as much information about yourself for the best experience of using our platform. To update your account information, go to the [Account](https://console.nebulablock.com/profile) tab in the [customer portal](https://console.nebulablock.com/home) and click "Edit Profile".

## Reset Password

If you forget your password, you can reset it via the [reset password page](https://console.nebulablock.com/forgot).

## Having Multiple Accounts

You can hold more than one Nebula Block account — for example to keep separate billing for separate projects — but **the same payment card cannot be added to more than one account**. Duplicate payment cards are rejected across accounts.

If what you actually need is shared access to one set of resources, use [Teams](/account/teams) instead of a second account. Teams give you shared billing, per-member roles, and team API keys.

## Deleting your account

Account deletion is permanent and cannot be reversed — the account cannot be reactivated afterwards. You can start it from [**Profile**](https://console.nebulablock.com/profile) in the console.

## See also

* [Billing](/getting-started/get-started/billing)
* [Tiers and Rate Limits](/account/tiers-and-limits)
* [Teams](/account/teams)


# Billing

How credits work on Nebula Block: payment cards, USDC, purchasing credit, auto-pay, invoices, and usage.

Everything on Nebula Block is paid for with **credits**. You buy credits up front, and usage — per-token inference, hourly instance charges, object storage egress — is deducted from that balance. Invoices are generated automatically for each purchase.

All of it is managed under [**Billing**](https://console.nebulablock.com/billing) in the console.

> **Note:** How much credit you have deposited or spent also determines your [tier](/account/tiers-and-limits), which sets your rate limits and whether you can rent CPU and GPU instances. How *much* GPU you can run at once is governed separately by your [hourly spending limit](/getting-started/get-started/spending-limits).

## Adding a Payment Card

To add a payment card, simply navigate to the "Add a New Card" button on the billing page and enter your card details. If the card meets the following requirements, it is added to your account successfully:

* Has valid card credentials (CVV, address, card number, etc.)
* Doesn't exist on another account
* Has enough funds available

Nebula Block accepts all types of payment cards. Note that your card may be validated for authenticity, but you will not be charged any amount during this process.

## Redeeming a Promotion Code

You can redeem a promotion code on the billing page. Simply enter your code in the "Add Promotion Code" section and click "Redeem" to apply the promotion to your account.

## Managing Payment Methods

Managing payment methods is simple via our customer portal. To change your default payment method, simply configure this in the [**Payment Method**](https://console.nebulablock.com/billing) section of the billing page.

## Purchasing Credits

Select the amount you want on the billing page and pay with your default card, a new card, or **USDC** if you prefer to pay in crypto.

## Configuring Auto-Pay

You can enable automatic billing (Auto-Pay) on the billing page. By adding a card to your account and configuring your Auto-Pay settings, your balance will be automatically reloaded when it nears your specified threshold. When your account balance falls below your chosen threshold, your default saved card will be charged the amount you set for Auto-Pay (maximum once per hour).

To set up Auto-Pay, toggle the Auto-Pay switch, set your threshold and reload amount, and save.

> **Important:** GPU and CPU instances are **deleted automatically if your credit runs out**. If you have anything long-running, turn Auto-Pay on — or watch for the low-balance alerts the console sends.

## Hourly Spending Limit

Every account has a ceiling on what its running instances may cost per hour, added together. New accounts start at **$5/hour** — which covers every single-GPU machine we offer — and the limit rises automatically as card payments settle, or on request. The **Hourly Spending Limit** card on the billing page shows your current limit, how much of it is in use, and lets you ask for more. Details: [Spending Limits](/getting-started/get-started/spending-limits).

## Invoices

Transactions made on your account (e.g. when you are billed for usage) will be documented as downloadable invoices and listed in the [**Transaction**](https://console.nebulablock.com/billing) section of the billing page.

## Usage

The [**Usages**](https://console.nebulablock.com/billing) section of the billing page breaks down what your credit is being spent on. For inference specifically, [Inference Usage](https://console.nebulablock.com/inference-usage) shows consumption by model and by API key.

## Credit limits

Each tier caps how much credit your account can hold — $20 at Tier 1 up to $2,000 at Tier 4. See [Tiers and Rate Limits](/account/tiers-and-limits).

## See also

* [Spending Limits](/getting-started/get-started/spending-limits)
* [Tiers and Rate Limits](/account/tiers-and-limits)
* [Billing API](/api-reference/platform-api/get-credit-balance)
* [Refund Policy](/resources/legal/refund-policy)


# Spending Limits

Every account has an hourly spending limit for GPU and CPU instances. What it is, how it grows on its own, and how to ask for more.

Every account has an **hourly spending limit**: the most your running instances can cost per hour, added together. It exists so that a compromised card or account cannot spin up a wall of GPUs before anyone notices — and it is sized so that a real customer rarely meets it.

The limit governs **scale**, not access. Which products you can use is decided by your [tier](/account/tiers-and-limits); how much of them you can run at once is decided by this limit. A brand-new account can launch any single-GPU machine in the catalogue on day one — the starting limit is set above the dearest one we sell.

## How it works

When you deploy an instance, the console adds its hourly price to what your other instances already cost per hour. If the total would exceed your limit, the deploy is declined with a message that says so — nothing is charged, and your running instances are not affected.

* The limit is per **billing account**. Instances launched by team members count against the **team owner**, who is the account that pays for them.
* Prices are compared in **$/h as listed** on the deploy page, before any coupon.
* Stopped instances that still hold hardware count; deleted instances do not.

You can see your current limit, how much of it is in use, and the ladder below under [**Billing → Hourly Spending Limit**](https://console.nebulablock.com/billing). The deploy page also shows it next to the price, and marks configurations that would take you past it.

## How it grows

The limit rises on its own as your account builds a payment history — there is nothing to apply for:

| Stage       | Limit           | How you get there                                                          |
| ----------- | --------------- | -------------------------------------------------------------------------- |
| New account | **$5 / hour**   | Sign up. Covers every single-GPU configuration we offer.                   |
| Settled     | **$20 / hour**  | A card payment on the account is 7 days old with no dispute.               |
| Trusted     | **$100 / hour** | $200 of settled payments (each 7 days old, undisputed) are on the account. |

"Settled" means the payment is old enough that it is very unlikely to be reversed. A payment that ends in a chargeback stops the automatic increases on that account — if that happens and you believe it is a mistake, [contact support](/resources/contact) and we will set your limit by hand.

Accounts that were already running instances when this limit was introduced were placed above anything they had ever run, so nothing changed for them.

## Asking for more

If you need a larger machine before your history gets you there — an 8-GPU node in your first week, say — request an increase from [**Billing → Hourly Spending Limit**](https://console.nebulablock.com/billing):

1. Enter the limit you need and a sentence or two on what you plan to run.
2. Submit. You can have one request open at a time.
3. Most requests are reviewed within a few hours; you will get a console notification with the outcome.

A limit granted this way is never lowered by the automatic ladder, and it can still rise on its own once your payment history earns a higher rung.

For team deployments, the **team owner** requests the increase, since the limit is theirs.

## Top-up security checks

Separately from the spending limit, the console may ask for **3-D Secure** (the verification step run by your card's bank) on a credit purchase, and may briefly pause additional card top-ups on an account that has just been created or has switched cards several times in a day. These checks protect you and us from stolen-card use; they do not affect credit you already hold. If a pause gets in the way of legitimate use, [contact support](/resources/contact) and we will lift it.

## See also

* [Billing](/getting-started/get-started/billing)
* [Tiers and Rate Limits](/account/tiers-and-limits)
* [GPU Cloud](/products/gpu-cloud)


# Products

What Nebula Block offers — serverless inference, GPU cloud, and object storage — and which tier each one needs.

Nebula Block runs three product lines that share one account, one credit balance, and one API key.

## Serverless Inference

Managed endpoints for state-of-the-art models — text, multimodal chat, vision, image generation, video generation, embeddings, and reranking. Nothing to provision: authenticate and call.

* **Endpoint:** `https://inference.nebulablock.com/v1` (OpenAI-compatible)
* **Billing:** pay-as-you-go, metered per token (per image or per second for some media models)
* **Access:** all tiers, but per-model daily caps apply — see [Tiers and Rate Limits](/account/tiers-and-limits)

→ [Serverless Inference](/products/serverless-inference) · [Model Catalog](/products/serverless-inference/model-catalog)

## GPU Cloud

On-demand GPU and CPU instances billed by the hour. Pick your hardware and OS image, attach an SSH key, and the instance is reachable in minutes. Instances can be started, stopped, rebooted, and firewalled from the console or the Platform API.

* **Access:** CPU instances from Tier 2, GPU instances from Tier 3
* **Billing:** hourly, deducted from your credit balance for as long as the instance exists — powered on or not

→ [GPU Cloud](/products/gpu-cloud) · [Quickstart](/products/gpu-cloud/quickstart)

> **Note:** Instances are deleted automatically if your credit balance runs out. Keep auto-pay on, or watch your balance, for anything long-running.

## Object Storage

S3-compatible object storage for datasets, checkpoints, and generated media. Works with `s3cmd`, `boto3`, and the AWS SDKs for Go and Java, and can be managed through the console or the Platform API.

→ [Object Storage](/products/object-storage) · [Quickstart](/products/object-storage/quickstart)

## Also available in the console

These are live in the [console](https://console.nebulablock.com) but not yet covered in depth by these docs:

|                          | What it is                                                            |
| ------------------------ | --------------------------------------------------------------------- |
| **Reserved Instances**   | Committed-term GPU capacity at a lower effective rate than on-demand  |
| **Dedicated Endpoints**  | Single-tenant inference deployments                                   |
| **Hardware Store**       | Purchase used and refurbished server hardware — GPUs, storage, memory |
| **Sovereign AI Compute** | Canadian-hosted compute and models for data-residency requirements    |

## See also

* [Quickstart](/getting-started/get-started/quickstart)
* [Billing Information](/getting-started/get-started/billing)
* [Tiers and Rate Limits](/account/tiers-and-limits)


# Serverless Inference

Run text, vision, image, video, embedding, and reranking models on managed OpenAI-compatible endpoints.

Serverless Inference gives you managed endpoints for state-of-the-art models — no GPUs to provision, no weights to load, no scaling to manage. Sign in, create a key, and call the API.

The endpoint is **OpenAI-compatible** and lives at `https://inference.nebulablock.com/v1`, so any OpenAI SDK or tool works by changing the base URL.

## What you can do

|                                                            | Guide                                                               |
| ---------------------------------------------------------- | ------------------------------------------------------------------- |
| Chat and text generation, including tool use and streaming | [Text Generation](/products/serverless-inference/text-generation)   |
| Send images to a model and ask about them                  | [Vision](/products/serverless-inference/vision)                     |
| Generate and edit images                                   | [Image Generation](/products/serverless-inference/image-generation) |
| Generate video from text or an image                       | [Video Generation](/products/serverless-inference/video-generation) |
| Turn text into vectors for search and RAG                  | [Embeddings](/products/serverless-inference/embeddings)             |
| Reorder retrieved documents by relevance                   | [Reranking](/products/serverless-inference/reranking)               |

The [Model Catalog](/products/serverless-inference/model-catalog) lists every model currently served, grouped by what it does.

## Prerequisites

* A [Nebula Block account](https://console.nebulablock.com/register)
* An [API key](/account/api-keys)
* Credit on your account — most models are capped at 0 requests per day on Tier 1, so a $5 deposit (Tier 2) is what opens up the catalog. See [Tiers and Rate Limits](/account/tiers-and-limits).

## Key features

* **OpenAI compatible.** Point the OpenAI Python, Node, or any compatible client at the base URL above.
* **One key, every modality.** Text, vision, image, video, embedding, and reranking models share the same authentication and the same base URL.
* **Pay as you go.** Billed on usage, metered per token — or per image or per second for some media models. See the [pricing page](https://www.nebulablock.com/pricing/serverless-ai).
* **Try before you integrate.** Every model has a playground in the console under [Serverless](https://console.nebulablock.com/serverless).
* **Canadian-hosted options.** Models marked 🇨🇦 in the catalog run in Canada for data-residency requirements.

## Rate limits

Two limits apply to every call: your account-wide rate limit (RPM, TPM, RPD) and a per-model daily cap that varies by tier. Both are documented in [Tiers and Rate Limits](/account/tiers-and-limits), and your account's current numbers are shown under [Limits](https://console.nebulablock.com/limits) in the console.

## See also

* [Quickstart](/getting-started/get-started/quickstart)
* [Inference API reference](/api-reference/inference-api)
* [Glossary](/resources/glossary)


# Model Catalog

Every model available on Nebula Block serverless inference, with model IDs and context lengths, grouped by capability.

Nebula Block serves every model below through one OpenAI-compatible endpoint at `https://inference.nebulablock.com/v1`, grouped here by what the model does.

Use the **Model ID** column as the `model` parameter in your API calls.

> **Note:** The catalog changes frequently. For a machine-readable list that is always current, call [`GET /v1/models`](/api-reference/inference-api/list-models), or browse [Serverless Models](https://console.nebulablock.com/serverless) in the console. Per-token pricing — including promotional rates — is published on the [pricing page](https://www.nebulablock.com/pricing/serverless-ai) and in the console, so this page deliberately does not duplicate it.

Models marked 🇨🇦 are hosted in Canada — relevant if you have data-residency requirements. See [Sovereign AI Compute](https://www.nebulablock.com/ai-sovereign-compute).

## Text generation and multimodal chat

Called through [Chat Completions](/api-reference/inference-api/chat-completions). Models listed as multimodal accept images alongside text in the same request.

| Model                                        | Model ID                                        | Context | Description                                                                                                    |
| -------------------------------------------- | ----------------------------------------------- | ------- | -------------------------------------------------------------------------------------------------------------- |
| **GLM-5.3**                                  | `zai-org/GLM-5.3`                               | 1M      | Z.ai's GLM-5.3, a 1M-token-context reasoning model with tool calling and structured outputs. Reasoning is…     |
| **GLM-5.3-Flash**                            | `zai-org/GLM-5.3-Flash`                         | 1M      | Z.ai's fast, low-cost GLM-5.3 variant with a 1M-token context window, image understanding and tool calling.…   |
| **Qwen3.8-27B**                              | `Qwen/Qwen3.8-27B`                              | 64K     | Qwen's compact 27B dense model from the Qwen3.8 generation, with strong agentic and coding performance, tool…  |
| **Gemini-3.7-Flash**                         | `gemini/gemini-3.7-flash`                       | 1M      | Google's newest Flash model — stronger multimodal reasoning, coding and agentic performance at Flash speed,…   |
| **Qwen3.8-2.4T-A95B**                        | `Qwen/Qwen3.8-2.4T-A95B`                        | 256K    | Alibaba's most capable open-weight model — a 2.4T-parameter Mixture-of-Experts with 95B active parameters per… |
| **DeepSeek-V4-Pro-0813**                     | `deepseek-ai/DeepSeek-V4-Pro-0813`              | 1M      | DeepSeek's GA release of V4 Pro, a large-scale mixture-of-experts model with a 1M-token context window and…    |
| **Grok-4.6**                                 | `x-ai/grok-4.6`                                 | 500K    | xAI's smartest model, with frontier performance on coding, knowledge work, and STEM. 500K-token context…       |
| **DeepSeek-V4-Flash-0731**                   | `deepseek-ai/DeepSeek-V4-Flash-0731`            | 1M      | DeepSeek's official V4 Flash release, superseding the preview with substantially stronger agentic and coding…  |
| **Claude-Opus-5**                            | `anthropic/claude-opus-5`                       | 1M      | Anthropic's most capable model for complex agentic coding and enterprise work, delivering a step-change in…    |
| **Gemini-3.6-Flash**                         | `gemini/gemini-3.6-flash`                       | 1M      | Google's latest Flash model — upgraded multimodal reasoning, coding and agentic performance at Flash speed…    |
| **Gemini-3.5-Flash-Lite**                    | `gemini/gemini-3.5-flash-lite`                  | 1M      | Google's most cost-efficient Gemini 3.5 model — low-latency multimodal inference tuned for high-volume…        |
| **Qwen3.8-Max-Preview**                      | `Qwen/Qwen3.8-Max-Preview`                      | 991K    | Alibaba Qwen 2.4T-parameter flagship preview with major gains in coding, full-stack development, data…         |
| **Kimi-K3**                                  | `moonshotai/Kimi-K3`                            | 1M      | Moonshot AI's flagship model with a 1M-token context window, built for long-horizon agentic coding and tool…   |
| **GPT-5.6-Sol**                              | `openai/gpt-5.6-sol`                            | 1.05M   | OpenAI GPT-5.6 Sol — flagship multimodal model in the GPT-5.6 series with top-tier reasoning and agentic…      |
| **GPT-5.6-Terra**                            | `openai/gpt-5.6-terra`                          | 1.05M   | OpenAI GPT-5.6 Terra — a balanced multimodal model in the GPT-5.6 series with strong reasoning, positioned…    |
| **Grok-4.5**                                 | `x-ai/grok-4.5`                                 | 500K    | xAI's flagship model released in July 2026, with frontier performance on coding, knowledge work, and STEM.…    |
| **Claude-Sonnet-5**                          | `anthropic/claude-sonnet-5`                     | 1M      | Anthropic's most capable mid-tier model, delivering near-Opus-level intelligence across coding, computer use,… |
| **Claude-Fable-5**                           | `anthropic/claude-fable-5`                      | 1M      | Anthropic's most capable frontier model for demanding reasoning and long-horizon agentic work, with always-on… |
| **MiniMax-M3**                               | `MiniMaxAI/MiniMax-M3`                          | 1M      | A million-token multimodal frontier model from MiniMax, built for long-horizon agentic work with native…       |
| **Qwen3.6-35B-A3B** 🇨🇦                     | `Qwen/Qwen3.6-35B-A3B`                          | 256K    | Qwen3.6 35B (3B-active) MoE with built-in NEXTN speculative decoding, reasoning and tool calling — fast…       |
| **Claude-Opus-4.8**                          | `anthropic/claude-opus-4-8`                     | 1M      | Anthropic's most capable generally available model, excelling at agentic coding, long-running tasks, and…      |
| **Gemini-3.5-Flash**                         | `gemini/gemini-3.5-flash`                       | 1M      | Latest Gemini 3.5 Flash — fast multimodal reasoning with 1M context                                            |
| **Gemini-3.1-Flash-Lite**                    | `gemini/gemini-3.1-flash-lite`                  | 1M      | Google's most cost-efficient, low-latency multimodal model in the Gemini 3 series, optimized for high-volume,… |
| **Grok-4.3**                                 | `x-ai/grok-4.3`                                 | 1M      | xAI's reasoning model released in late April 2026, featuring always-on reasoning, a 1-million-token context…   |
| **GPT-5.5**                                  | `openai/gpt-5.5`                                | 400K    | OpenAI's next-generation multimodal GPT-5.5 model with improved token efficiency for hard reasoning, coding,…  |
| **DeepSeek-V4-Pro**                          | `deepseek-ai/DeepSeek-V4-Pro`                   | 1M      | DeepSeek's next-generation flagship language model delivering state-of-the-art reasoning, coding, and agentic… |
| **DeepSeek-V4-Flash**                        | `deepseek-ai/DeepSeek-V4-Flash`                 | 1M      | DeepSeek's fast, cost-efficient V4 variant optimized for high-throughput reasoning and coding with a 1M…       |
| **MiMo-V2.5-Pro**                            | `XiaomiMiMo/MiMo-V2.5-Pro`                      | 1M      | Xiaomi's flagship text model tuned for complex software engineering, agentic workflows, and long-horizon…      |
| **MiMo-V2.5**                                | `XiaomiMiMo/MiMo-V2.5`                          | 1M      | Xiaomi's natively omnimodal model accepting text, image, audio, and video inputs with a 1M context window for… |
| **Gemma-4-31B**                              | `google/gemma-4-31b-it`                         | 128K    | Google DeepMind's open-weights, instruction-tuned multimodal model optimized for reasoning, coding, and…       |
| **Claude-Opus-4.7**                          | `anthropic/claude-opus-4-7`                     | 1M      | Anthropic's most capable generally available model, excelling at agentic coding, long-running tasks, and…      |
| **MiMo-V2-Omni**                             | `XiaomiMiMo/MiMo-V2-Omni`                       | 256K    | Xiaomi's omni-modal agent model that natively understands text, images, video, and audio in a unified…         |
| **Mistral-Small-4**                          | `mistralai/Mistral-Small-4-119B-2603`           | 256K    | A large (\~119B parameter) dense language model designed for efficient, high-quality text generation and…      |
| **Gemini-3.1-Flash-Lite-Preview**            | `gemini/gemini-3.1-flash-lite-preview`          | 1M      | Google’s fastest and most cost-efficient Gemini 3 model, optimized for high-throughput tasks and scalable…     |
| **Gemini-3.1-Pro-Preview**                   | `gemini/gemini-3.1-pro-preview`                 | 1M      | Google's frontier reasoning model that builds on the Gemini 3 Pro series with enhanced thinking capabilities,… |
| **MiMo-V2-Pro**                              | `XiaomiMiMo/MiMo-V2-Pro`                        | 1M      | A trillion-parameter text-only flagship agent model from Xiaomi, built for complex coding, long-horizon…       |
| **MiniMax-M2.7**                             | `MiniMaxAI/MiniMax-M2.7`                        | 200K    | A next-generation agentic LLM with native interleaved thinking, built for complex real-world productivity…     |
| **GLM-4.7-Flash**                            | `zai-org/GLM-4.7-Flash`                         | 128K    | A 30B Mixture-of-Experts language model optimized for efficient inference, strong coding performance, and…     |
| **Qwen3.5-Plus**                             | `Qwen/Qwen3.5-Plus`                             | 1M      | Alibaba's native vision-language model with a 1M-token context window, hybrid MoE architecture, and built-in…  |
| **Kimi-K2.5**                                | `moonshotai/Kimi-K2.5`                          | 256K    | An open-source native multimodal AI model that combines vision and language understanding with advanced…       |
| **Claude-Sonnet-4.6**                        | `anthropic/claude-sonnet-4-6`                   | 1M      | Anthropic's most capable mid-tier model, delivering near-Opus-level intelligence across coding, computer use,… |
| **Claude-Opus-4.6**                          | `anthropic/claude-opus-4-6`                     | 1M      | Anthropic's most intelligent model, excelling at complex reasoning, coding, analysis, and multi-step tasks     |
| **Claude-Opus-4.5**                          | `anthropic/claude-opus-4-5-20251101`            | 200K    | An advanced flagship model delivering top-tier reasoning, deep analysis, and long-context performance for the… |
| **Claude-Haiku-4.5**                         | `anthropic/claude-haiku-4-5-20251001`           | 200K    | A lightweight, low-latency model built for rapid responses, simple reasoning, and high-throughput applications |
| **Claude-Sonnet-4.5**                        | `anthropic/claude-sonnet-4-5-20250929`          | 1M      | A fast, cost-efficient model optimized for everyday reasoning, coding, and high-quality conversational tasks   |
| **Claude-Opus-4**                            | `anthropic/claude-opus-4-20250514`              | 200K    | Top-tier, large-scale reasoning model designed for complex analysis, long-context understanding, and…          |
| **Grok-4-Fast**                              | `x-ai/grok-4-fast`                              | 2M      | High-performance open-source MoE language model optimized for reasoning, coding, and efficient text generation |
| **Gemini-3-Flash-Preview**                   | `gemini/gemini-3-flash-preview`                 | 1M      | Google’s agentic workhorse model, bringing near Pro agentic, coding and multimodal intelligence, with more…    |
| **Gemini-3-Pro-Preview**                     | `gemini/gemini-3-pro-preview`                   | 1M      | Google’s latest multimodal AI model that combines advanced reasoning, coding, and image-video understanding…   |
| **Gemini-2.5-Pro**                           | `gemini/gemini-2.5-pro`                         | 1M      | Strongest Gemini, 1M context, great for code & knowledge                                                       |
| **Gemini-2.5-Flash**                         | `gemini/gemini-2.5-flash`                       | 1M      | Fast reasoning with improved latency & accuracy                                                                |
| **Gemini-2.5-Flash-Lite**                    | `gemini/gemini-2.5-flash-lite`                  | 1M      | Ultra-low latency Gemini variant                                                                               |
| **GPT-5.4**                                  | `openai/gpt-5.4`                                | 400K    | A frontier large language model optimized for complex professional tasks, combining strong reasoning, coding,… |
| **GPT-5.3-Chat**                             | `openai/gpt-5.3-chat`                           | 400K    | A fast, general-purpose conversational LLM based on the GPT-5.3 architecture, optimized for high-quality…      |
| **GPT-5.3-Codex**                            | `openai/gpt-5.3-codex`                          | 400K    | A high-performance agentic coding model designed to autonomously write, debug, and manage complex software…    |
| **GPT-5.2**                                  | `openai/gpt-5.2`                                | 400K    | OpenAI’s flagship multimodal (text + image) GPT-5.2 model for top-tier coding and agentic tasks, producing…    |
| **GPT-5.1**                                  | `openai/gpt-5.1`                                | 400K    | OpenAI’s multimodal (text + image) GPT-5 model for strong coding, reasoning, and agentic tasks across…         |
| **GPT-5**                                    | `openai/gpt-5`                                  | 400K    | OpenAI’s multimodal (text + image) GPT-5 model for strong coding, reasoning, and agentic tasks across…         |
| **GPT-5-Mini**                               | `openai/gpt-5-mini`                             | 400K    | OpenAI’s faster, more cost-efficient GPT-5 model for well-defined tasks, supporting text and image input with… |
| **GPT-5-Nano**                               | `openai/gpt-5-nano`                             | 400K    | OpenAI’s fastest, most cost-efficient GPT-5 model for lightweight tasks like summarization and…                |
| **GPT-4o-mini**                              | `openai/gpt-4o-mini`                            | 125K    | Compact GPT-4 Omni, supports text & image inputs                                                               |
| **GLM-5**                                    | `zai-org/GLM-5`                                 | 198K    | Z.ai's most powerful model — a 744B-parameter (40B active) open-source MoE optimized for reasoning, coding,…   |
| **GLM-4.7**                                  | `zai-org/GLM-4.7`                               | 198K    | An open-weights MoE chat model from Z.ai optimized for strong reasoning and tool-using agents                  |
| **Kimi-K2-Thinking**                         | `moonshotai/Kimi-K2-Thinking`                   | 256K    | 1T-parameter reasoning-focused language model designed for complex, multi-step problem solving and tool use    |
| **DeepSeek-V3.2**                            | `deepseek-ai/DeepSeek-V3.2`                     | 160K    | A high-performance open-weight large language model from DeepSeek optimized for strong reasoning, coding, and… |
| **DeepSeek-V3.2-Exp**                        | `deepseek-ai/DeepSeek-V3.2-Exp`                 | 160K    | Experimental version with sparse-attention architecture for long-context efficiency                            |
| **DeepSeek-V3.1**                            | `deepseek-ai/DeepSeek-V3.1`                     | 160K    | Hybrid inference LLM with Think/Non-Think modes, 128K context, advanced agent                                  |
| **DeepSeek-V3-0324**                         | `deepseek-ai/DeepSeek-V3-0324`                  | 64K     | High-performance open-source MoE language model optimized for reasoning, coding, and efficient text generation |
| **DeepSeek-R1-0528**                         | `deepseek-ai/DeepSeek-R1-0528`                  | 160K    | An open-source next-generation reasoning-optimized language model with enhanced logic, math, and code…         |
| **Qwen3-235B-A22B-Instruct-2507**            | `Qwen/Qwen3-235B-A22B-Instruct-2507`            | 256K    | A 235B-parameter MoE instruction-tuned language model for general, multilingual, and coding tasks              |
| **Mistral-Small-3.2-24B-Instruct-2506** 🇨🇦 | `mistralai/Mistral-Small-3.2-24B-Instruct-2506` | 32K     | 24B instruction model, long context, fewer errors                                                              |
| **Llama3.3-70B**                             | `meta-llama/Llama-3.3-70B-Instruct`             | 38K     | Multilingual 70B delivering 405B-level performance                                                             |
| **Kimi-K2.6**                                | `moonshotai/Kimi-K2.6`                          | 256K    | An open-weight 1T-parameter MoE multimodal model built for long-horizon agentic coding, with a 256K context…   |

## Vision

Dedicated vision-language models for image understanding. See [Vision](/products/serverless-inference/vision).

| Model                      | Model ID                      | Context | Description                                                                                                   |
| -------------------------- | ----------------------------- | ------- | ------------------------------------------------------------------------------------------------------------- |
| **Qwen3-VL-Plus**          | `Qwen/Qwen3-VL-Plus`          | 256K    | Alibaba's multimodal vision-language API model that handles text, image, and video inputs with strong visual… |
| **Qwen3-VL-Flash**         | `Qwen/Qwen3-VL-Flash`         | 256K    | Alibaba's lightweight, cost-effective multimodal vision-language API model designed for fast inference on…    |
| **Qwen2.5-VL-7B-Instruct** | `Qwen/Qwen2.5-VL-7B-Instruct` | 125K    | Vision-language model for multimodal understanding                                                            |

## Image generation

Called through [Images](/api-reference/inference-api/images). See [Image Generation](/products/serverless-inference/image-generation).

| Model                      | Model ID                                | Modalities                         | Description                                                                                                 |
| -------------------------- | --------------------------------------- | ---------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| **Nano-Banana-2**          | `gemini/gemini-3.1-flash-image-preview` | text\_to\_image, image\_generation | Text-to-image and image+text-to-image with up to 14 reference images. Supports aspect\_ratio, image\_size,… |
| **Nano-Banana-Pro-Edit**   | `gemini/gemini-3-pro-image-edit`        | image\_to\_image, text\_to\_image  | Premium AI-powered image editing with Gemini 3 Pro. Advanced editing capabilities with better quality,…     |
| **Nano-Banana-Pro**        | `gemini/gemini-3-pro-image-preview`     | text\_to\_image                    | High-quality image generation with better text rendering, character consistency, and advanced composition.… |
| **Nano-Banana-Edit**       | `gemini/gemini-2.5-flash-image-edit`    | image\_to\_image, text\_to\_image  | AI-powered image editing with Gemini 2.5 Flash. Edit images using natural language instructions - remove…   |
| **Bytedance-Seedream-3.0** | `Bytedance/seedream-3-0-t2i-250415`     | text\_to\_image, image\_to\_image  | Bilingual text-to-image, 2K resolution, accurate text & artistic layouts                                    |

## Video generation

Called through [Videos](/api-reference/inference-api/videos). See [Video Generation](/products/serverless-inference/video-generation).

| Model                                | Model ID                                | Modalities                                          | Description                                                                                                  |
| ------------------------------------ | --------------------------------------- | --------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| **Seedance-2.0**                     | `Byteplus/seedance-2-0-260128`          | text\_to\_video, image\_to\_video, video\_to\_video | BytePlus Seedance 2.0 — unified multimodal video (text/image/video/audio refs, native audio). Billed on…     |
| **Seedance-2.0-Fast**                | `Byteplus/seedance-2-0-fast-260128`     | text\_to\_video, image\_to\_video, video\_to\_video | BytePlus Seedance 2.0 Fast — faster/cheaper variant (no 1080p). Billed on actual tokens.                     |
| **Seedance-2.0-Mini**                | `Byteplus/seedance-2-0-mini-260615`     | text\_to\_video, image\_to\_video, video\_to\_video | BytePlus Seedance 2.0 Mini — cost-effective variant (no 1080p). Billed on actual tokens.                     |
| **Veo-3.1-Fast**                     | `Google/veo-3.1-fast`                   | text\_to\_video                                     | Google Veo 3.1 Fast - Fast and economical text-to-video generation. Supports up to 8 seconds at 720p/1080p.… |
| **Veo-3.1-Fast-I2V**                 | `Google/veo-3.1-fast-i2v`               | image\_to\_video                                    | Google Veo 3.1 Fast Image-to-Video - Generate video from an input image. Supports up to 8 seconds at…        |
| **Veo-3.1**                          | `Google/veo-3.1`                        | text\_to\_video                                     | Google Veo 3.1 Standard - Balanced quality and speed for text-to-video generation. Supports up to 8 seconds… |
| **Veo-3.1-I2V**                      | `Google/veo-3.1-i2v`                    | image\_to\_video                                    | Google Veo 3.1 Standard Image-to-Video - Generate high-quality video from an input image.                    |
| **Seedance-1.0-Pro-Image-to-Video**  | `Byteplus/seedance-1-0-pro-250528`      | image\_to\_video                                    | Pro-tier model, turns images into cinematic 1080p videos with smooth motion                                  |
| **Seedance-1.0-Pro-Text-to-Video**   | `Byteplus/seedance-1-0-pro-250528`      | text\_to\_video                                     | Pro-tier text-to-video, generates multi-shot 1080p videos with narrative flow                                |
| **Seedance-1.0-Lite-Image-to-Video** | `Byteplus/seedance-1-0-lite-i2v-250428` | image\_to\_video                                    | Lite version, quick image-to-video at up to 1080p, shorter sequences                                         |
| **Seedance-1.0-Lite-Text-to-Video**  | `Byteplus/seedance-1-0-lite-t2v-250428` | text\_to\_video                                     | Lite text-to-video, faster, lower compute, shorter outputs                                                   |

## Embeddings

Called through [Embeddings](/api-reference/inference-api/embeddings). See [Embeddings](/products/serverless-inference/embeddings).

| Model                       | Model ID                  | Parameters | Description                                                             |
| --------------------------- | ------------------------- | ---------- | ----------------------------------------------------------------------- |
| **Qwen3-Embedding-8B** 🇨🇦 | `Qwen/Qwen3-Embedding-8B` | 8B         | 8B embedding model, strong multilingual & code support, top MTEB scorer |

## Reranking

Called through [Rerank](/api-reference/inference-api/rerank). See [Reranking](/products/serverless-inference/reranking).

| Model                       | Model ID                  | Parameters | Description                                                                |
| --------------------------- | ------------------------- | ---------- | -------------------------------------------------------------------------- |
| **BGE-reranker-v2-m3** 🇨🇦 | `BAAI/bge-reranker-v2-m3` | 568M       | Multilingual reranker, query+passage → relevance score, lightweight & fast |

## Model access by tier

Every model carries a per-tier daily request cap, and on **Tier 1 that cap is 0 for most of the catalog** — a $5 deposit (Tier 2) is what unlocks it. Check the exact cap for your account under [Limits](https://console.nebulablock.com/limits) in the console, and see [Tiers and Rate Limits](/account/tiers-and-limits) for the full picture.

## See also

* [Serverless Inference overview](/products/serverless-inference)
* [List Models API](/api-reference/inference-api/list-models)
* [Tiers and Rate Limits](/account/tiers-and-limits)


# Text Generation

Generate text and hold conversations with Nebula Block's chat models using the OpenAI-compatible API.

Use these models to generate text, whether it's to review code, write a story, etc.

## Models available

Nebula Block serves dozens of text and multimodal chat models — including the latest from Anthropic, OpenAI, Google, DeepSeek, Qwen, Moonshot, xAI, and Z.ai. The [Model Catalog](/products/serverless-inference/model-catalog#text-generation-and-multimodal-chat) has the full list with context lengths and model IDs.

A few widely used ones:

| Model            | Model ID                            |
| ---------------- | ----------------------------------- |
| DeepSeek-V3.2    | `deepseek-ai/DeepSeek-V3.2`         |
| Claude Sonnet 5  | `anthropic/claude-sonnet-5`         |
| GPT-5.6          | `openai/gpt-5.6-terra`              |
| Gemini 3.7 Flash | `gemini/gemini-3.7-flash`           |
| Qwen3.5-Plus     | `Qwen/Qwen3.5-Plus`                 |
| Llama 3.3 70B    | `meta-llama/Llama-3.3-70B-Instruct` |

> **Note:** Model availability changes often. Call [`GET /v1/models`](/api-reference/inference-api/list-models) for the authoritative list at runtime rather than hard-coding one.

## Using the Models

1. Sign in to the [console](https://console.nebulablock.com) and make sure you have credit.
2. Open [**Serverless**](https://console.nebulablock.com/serverless) and pick a model.
3. Set your parameters, type your prompt, and send it.

The parameters you can tweak are outlined below:

* Messages: The current dialogue between the user and the model.
* System Prompt: Set of instructions, guidelines, and contextual information, which tell the AI how to respond to the queries.
* Output Length: The maximum number of tokens that will be generated for each response.
* Temperature: Temperature controls randomness. Higher values increase diversity.
* Top P: A higher value will result in more diverse outputs, while a lower value will result in more repetitive outputs.
* Stream: If set to `true`, the response will be streamed in chunks. If False, the entire generation will be returned in one response.

### Through API Endpoint

This option is to use our API endpoint directly in your projects. Below are some code snippets to get you started!

> **NOTE:** Don't forget to use **your** API key. See the [API Reference](/api-reference/authentication) and the [Overview](/account/api-keys) for more details on authentication.

#### Using cURL

```bash
curl -X POST "https://inference.nebulablock.com/v1/chat/completions" \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $NEBULA_API_KEY" \
    --data-raw '{
        "messages": [
	  {"role":"user","content":"Is Montreal a thriving hub for the AI industry?"}
	],
        "model": "meta-llama/Llama-3.3-70B-Instruct",
        "max_tokens": null, 
        "temperature": 1,
        "top_p": 0.9,
        "stream": false
    }'
```

#### Using Python

```python
import requests 
import os
 
url = "https://inference.nebulablock.com/v1/chat/completions"

headers = { 
    "Content-Type": "application/json", 
    "Authorization": f"Bearer {os.environ.get('NEBULA_API_KEY')}" 
} 
 
data = {
    "messages":[
		{"role":"user","content":"Is Montreal a thriving hub for the AI industry?"}
	],
    "model":"meta-llama/Llama-3.3-70B-Instruct",
    "max_tokens":None,
    "temperature":1,
    "top_p":0.9,
    "stream":False
}

response = requests.post(url, headers=headers, json=data) 
print(response.json())
```

#### Using JavaScript

```javascript
const url = "https://inference.nebulablock.com/v1/chat/completions";

const headers = {
    "Content-Type": "application/json",
    "Authorization": `Bearer ${process.env.NEBULA_API_KEY}`
};

const data = {
    messages: [
        { role: "user", content: "Is Montreal a thriving hub for the AI industry?" }
    ],
    model: "meta-llama/Llama-3.3-70B-Instruct",
    max_tokens: null,
    temperature: 1,
    top_p: 0.9,
    stream: false
};

fetch(url, {
    method: 'POST',
    headers: headers,
    body: JSON.stringify(data)
})
    .then(response => response.json())
    .then(data => {
        console.log(JSON.stringify(data, null, 2));
    })
    .catch(error => console.error('Error:', error));
```

#### Selecting a Model

To specify the desired model, use this mapping for the `model_name`:

* DeepSeek-R1-0528 (free):

  ```python
  deepseek-ai/DeepSeek-R1-0528-Free
  ```
* DeepSeek-V3-0324 (free):

  ```python
  deepseek-ai/DeepSeek-V3-0324-Free
  ```
* DeepSeek-V3-0324:

  ```python
  deepseek-ai/DeepSeek-V3-0324
  ```
* DeepSeek-R1 (free):

  ```python
  deepseek-ai/DeepSeek-R1-Free
  ```
* DeepSeek-R1-0528:

  ```python
  deepseek-ai/DeepSeek-R1-0528
  ```
* DeepSeek-R1:

  ```python
  deepseek-ai/DeepSeek-R1
  ```
* Llama3.3-70B:

  ```python
  meta-llama/Llama-3.3-70B-Instruct
  ```
* Qwen-QwQ-32B:

  ```python
  Qwen/QwQ-32B
  ```

#### Response Example

A successful generation response (non-streaming) will contain a `chat.completion` object, and should look like this:

```json
{
    "id": "chatcmpl-ec0014bc38e2cad1e45d47f7f01f6569",
    "created": 1740432179,
    "model": "meta-llama/Llama-3.3-70B-Instruct",
    "object": "chat.completion",
    "system_fingerprint": null,
    "choices": [
        {
            "finish_reason": "stop",
            "index": 0,
            "message": {
                "content": "Yes! Montreal is the home of cutting edge ... research.",
                "role": "assistant",
                "tool_calls": null,
                "function_call": null
            }
        }
    ],
    "usage": {
        "completion_tokens": 695,
        "prompt_tokens": 42,
        "total_tokens": 737,
        "completion_tokens_details": null,
        "prompt_tokens_details": null
    },
    "service_tier": null,
    "prompt_logprobs": null
}
```

This represents the entire generated response from the inference. Alternatively, the streaming option (`stream: true` in the request body) will return several responses, each containing a `chat.completion.chunk` object, and will look like this:

```json
{
    "id": "chatcmpl-289eb1f670a58c5cde47ddb634aad595",
    "created": 1740432271,
    "model": "meta-llama/Llama-3.3-70B-Instruct",
    "object": "chat.completion.chunk",
    "choices": [
        {
            "index": 0,
            "delta": {
                "content": " everyone"
            }
        }
    ]
}
{ 
  ...
}
...
```

where the content of each response will contain the generated token. These tokens put together form the complete response.

Feel free to explore refer to the [API Reference](/api-reference/inference-api/chat-completions) for more details.\
cat Inference\_Models/Text\_Generation.md


# Vision

Send images to vision and multimodal models on Nebula Block and ask questions about them.

**Vision models** behave similarly to text models, but they can accept and interpret images as well.

## Models available

Two kinds of model can take images:

**Dedicated vision-language models**

| Model                  | Model ID                      | Context |
| ---------------------- | ----------------------------- | ------- |
| Qwen3-VL-Plus          | `Qwen/Qwen3-VL-Plus`          | 256K    |
| Qwen3-VL-Flash         | `Qwen/Qwen3-VL-Flash`         | 256K    |
| Qwen2.5-VL-7B-Instruct | `Qwen/Qwen2.5-VL-7B-Instruct` | 32K     |

**Multimodal chat models.** Most of the flagship chat models — Claude, GPT, Gemini, and others — accept images in the same `messages` array as text. See the [Model Catalog](/products/serverless-inference/model-catalog#text-generation-and-multimodal-chat); anything listed as multimodal works with the requests on this page.

## Using the Models

1. Sign in to the [console](https://console.nebulablock.com) and make sure you have credit.
2. Open [**Serverless**](https://console.nebulablock.com/serverless) and pick a vision or multimodal model.
3. Set your parameters, add your image and prompt, and send it.

The parameters to tweak are the same as in [Text Generation](/products/serverless-inference/text-generation), with the addition of the following:

* **Image**: The image to be processed by the model.

### Through API Endpoint

This option is to use our API endpoint directly in your projects. Below are some code snippets to get you started!

> **NOTE:** Don't forget to use **your** API key. See the [API Reference](/api-reference/authentication) and the [Overview](/account/api-keys) for more details on authentication.

#### Using cURL

```bash
curl -X POST "https://inference.nebulablock.com/v1/chat/completions" \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $NEBULA_API_KEY" \
    --data-raw '{
        "messages": [
			{"role":"user","content":[
			{"type":"image_url","image_url":
			{"url":"https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen-VL/assets/demo.jpeg"}},
			{"type":"text","text":"What is this image?"}
		]}],
        "model": "Qwen/Qwen2.5-VL-7B-Instruct",
        "max_tokens": null, 
        "temperature": 1,
        "top_p": 0.9,
        "stream": false
    }'
```

#### Using Python

```python
import requests 
import os
 
url = "https://inference.nebulablock.com/v1/chat/completions"

headers = { 
    "Content-Type": "application/json", 
    "Authorization": f"Bearer {os.environ.get('NEBULA_API_KEY')}" 
} 
 
data = {
    "messages":[
		{"role":"user","content":[
		{"type":"image_url","image_url":
		{"url":"https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen-VL/assets/demo.jpeg"}},
		{"type":"text","text":"What is this image?"}
	]}],
    "model":"Qwen/Qwen2.5-VL-7B-Instruct",
    "max_tokens":None,
    "temperature":1,
    "top_p":0.9,
    "stream":False
}

response = requests.post(url, headers=headers, json=data) 
print(response.json())
```

#### Using JavaScript

```javascript
const url = "https://inference.nebulablock.com/v1/chat/completions";

const headers = {
    "Content-Type": "application/json",
    "Authorization": `Bearer sk-kmlKFCXGBZl-PS0MLnpzAw`
};

const data = {
    messages: [
        {"role":"user","content":[
        {"type":"image_url","image_url":
        {"url":"https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen-VL/assets/demo.jpeg"}},
        {"type":"text","text":"What is this image?"}
    ]}],
    model: 'Qwen/Qwen2.5-VL-7B-Instruct',
    max_tokens: null,
    temperature: 1,
    top_p: 0.9,
    stream: false
};

fetch(url, {
    method: 'POST',
    headers: headers,
    body: JSON.stringify(data)
})
    .then(response => response.json())
    .then(data => {
        console.log(JSON.stringify(data, null, 2));
    })
    .catch(error => console.error('Error:', error));
```

#### Selecting a Model

To specify the desired model, use this mapping for the `model_name`:

* Qwen2.5-VL-7B-Instruct: `Qwen/Qwen2.5-VL-7B-Instruct`

#### Response Example

A successful generation response (non-streaming) will contain a `chat.completion` object, and should look like this:

```json
    {
    "id": "chatcmpl-7ba48f119a564f4ea02b6a41386a3e40",
    "created": 1740689977,
    "model": "Qwen/Qwen2.5-VL-7B-Instruct",
    "object": "chat.completion",
    "system_fingerprint": null,
    "choices": [
        {
            "finish_reason": "stop",
            "index": 0,
            "message": {
                "content": "This image shows ....",
                "role": "assistant",
                "tool_calls": null,
                "function_call": null
            }
        }
    ],
    "usage": {
        "completion_tokens": 91,
        "prompt_tokens": 3604,
        "total_tokens": 3695,
        "completion_tokens_details": null,
        "prompt_tokens_details": null
    },
    "service_tier": null,
    "prompt_logprobs": null
}
```

As is the case with text generation, this represents the entire generated response, and setting the `stream` parameter to `True` will return the response in chunks:

```json
{
    "id": "chatcmpl-3812731562554b23a32dd80fbb7d0d09",
    "created": 1740692435,
    "model": "Qwen/Qwen2.5-VL-7B-Instruct",
    "object": "chat.completion.chunk",
    "choices": [
        {
            "index": 0,
            "delta": {
                "content": " setting"
            }
        }
    ]
}
{ 
  ...
}
...
```

with the collection of chunks forming the entire response.

Feel free to explore refer to the [API Reference](/api-reference/inference-api/vision) for more details.


# Image Generation

Generate and edit images on Nebula Block with Nano Banana and Seedream through the OpenAI-compatible images API.

Generate images from a text prompt, or edit an existing image, through the OpenAI-compatible images endpoint.

## Models available

| Model                  | Model ID                                | Does                                     |
| ---------------------- | --------------------------------------- | ---------------------------------------- |
| Nano-Banana-2          | `gemini/gemini-3.1-flash-image-preview` | Text-to-image, up to 14 reference images |
| Nano-Banana-Pro        | `gemini/gemini-3-pro-image-preview`     | Text-to-image, highest quality           |
| Nano-Banana-Pro-Edit   | `gemini/gemini-3-pro-image-edit`        | Image editing                            |
| Nano-Banana-Edit       | `gemini/gemini-2.5-flash-image-edit`    | Image editing                            |
| Bytedance-Seedream-3.0 | `Bytedance/seedream-3-0-t2i-250415`     | Bilingual text-to-image, native 2K       |

See the [Model Catalog](/products/serverless-inference/model-catalog#image-generation) for the current list.

## Generate an image

### Using cURL

```bash
curl -X POST "https://inference.nebulablock.com/v1/images/generations" \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $NEBULA_API_KEY" \
    --data-raw '{
        "model": "gemini/gemini-3.1-flash-image-preview",
        "prompt": "A snowy street in Old Montreal at dusk, warm window light, film photography",
        "size": "1536x1024"
    }'
```

### Using Python

```python
import base64
import os

from openai import OpenAI

client = OpenAI(
    base_url="https://inference.nebulablock.com/v1",
    api_key=os.environ["NEBULA_API_KEY"],
)

result = client.images.generate(
    model="gemini/gemini-3.1-flash-image-preview",
    prompt="A snowy street in Old Montreal at dusk, warm window light, film photography",
    size="1536x1024",
)

with open("output.png", "wb") as f:
    f.write(base64.b64decode(result.data[0].b64_json))
```

### Using JavaScript

```javascript
import fs from "node:fs";
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://inference.nebulablock.com/v1",
  apiKey: process.env.NEBULA_API_KEY,
});

const result = await client.images.generate({
  model: "gemini/gemini-3.1-flash-image-preview",
  prompt: "A snowy street in Old Montreal at dusk, warm window light, film photography",
  size: "1536x1024",
});

fs.writeFileSync("output.png", Buffer.from(result.data[0].b64_json, "base64"));
```

The response follows the OpenAI shape — a `created` timestamp and a `data` array whose entries carry `b64_json`.

## Controlling the output

`size` takes a `WxH` string and is mapped to the nearest aspect ratio the model supports: `1:1`, `16:9`, `9:16`, `4:3`, `3:4`, `3:2`, `2:3`, `21:9`, `4:5`, and `5:4`.

For anything a model supports beyond the OpenAI fields, use `provider_options`:

| Option                | Description                                          |
| --------------------- | ---------------------------------------------------- |
| `aspect_ratio`        | Set the ratio directly instead of via `size`         |
| `image_size`          | Output resolution, where the model supports multiple |
| `image_urls`          | Reference images to condition the generation on      |
| `person_generation`   | The model's policy for generating people             |
| `output_mime_type`    | Output format, such as `image/png` or `image/jpeg`   |
| `compression_quality` | Compression quality for lossy formats                |
| `thinking_level`      | How much the model reasons before generating         |

```bash
curl -X POST "https://inference.nebulablock.com/v1/images/generations" \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $NEBULA_API_KEY" \
    --data-raw '{
        "model": "gemini/gemini-3.1-flash-image-preview",
        "prompt": "Same scene, but in summer",
        "provider_options": {
            "aspect_ratio": "16:9",
            "output_mime_type": "image/png"
        }
    }'
```

## Edit an image

Editing takes a multipart upload rather than JSON, and needs one of the edit models:

```bash
curl -X POST "https://inference.nebulablock.com/v1/images/edits" \
    -H "Authorization: Bearer $NEBULA_API_KEY" \
    -F 'model=gemini/gemini-2.5-flash-image-edit' \
    -F 'prompt=Replace the sky with an aurora' \
    -F 'size=1024x1024' \
    -F 'image=@./input.png'
```

Accepted input formats are PNG, JPEG, WebP, and GIF.

## Through the console

Every image model has a playground under [**Serverless**](https://console.nebulablock.com/serverless) — useful for finding a prompt and a model before you write any code.

## Cost

Image models are billed per generation, and prices carry promotional rates from time to time. Check the [pricing page](https://www.nebulablock.com/pricing/serverless-ai) or the model's card in the console for the current rate.

## See also

* [Images API reference](/api-reference/inference-api/images)
* [Video Generation](/products/serverless-inference/video-generation)
* [Model Catalog](/products/serverless-inference/model-catalog)


# Video Generation

Generate video from text or an image with Veo 3.1 and Seedance using Nebula Block's asynchronous video API.

Nebula Block hosts text-to-video and image-to-video models — Google Veo 3.1 and BytePlus Seedance — behind an OpenAI-compatible endpoint.

Video generation takes anywhere from seconds to minutes, so the API is **asynchronous**: you submit a job, get a generation ID back immediately, and poll (or stream) until it is done.

## Models available

See the [Model Catalog](/products/serverless-inference/model-catalog#video-generation) for the current list. Models whose ID ends in `-i2v` are image-to-video and **require** an input image.

| Family                                          | Capabilities                                        |
| ----------------------------------------------- | --------------------------------------------------- |
| `Google/veo-3.1`, `Google/veo-3.1-fast`         | Text-to-video, optional generated audio             |
| `Google/veo-3.1-i2v`, `Google/veo-3.1-fast-i2v` | Image-to-video                                      |
| `Byteplus/seedance-2-0-*`                       | Text-, image-, and video-to-video with native audio |
| `Byteplus/seedance-1-0-*`                       | Text- and image-to-video                            |

## Generate a video

### 1. Submit the job

```bash
curl -X POST "https://inference.nebulablock.com/v1/videos/generations" \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $NEBULA_API_KEY" \
    --data-raw '{
        "model": "Google/veo-3.1-fast",
        "prompt": "A time-lapse of the Montreal skyline at sunset, cinematic, 35mm",
        "n_seconds": 5,
        "resolution": "720p",
        "aspect_ratio": "16:9",
        "include_audio": false
    }'
```

The response comes back immediately with a status of `pending`:

```json
{
  "id": "b3f1c0e2-6d1a-4e2b-9f77-6a1a2b3c4d5e",
  "object": "video.generation",
  "created_at": 1756944000,
  "status": "pending",
  "model": "Google/veo-3.1-fast",
  "estimated_cost": 0.6
}
```

### 2. Poll for the result

```bash
curl "https://inference.nebulablock.com/v1/videos/generations/$GENERATION_ID" \
    -H "Authorization: Bearer $NEBULA_API_KEY"
```

When `status` becomes `completed`, the response carries a `url` you can download the video from:

```json
{
  "id": "b3f1c0e2-6d1a-4e2b-9f77-6a1a2b3c4d5e",
  "object": "video.generation",
  "created_at": 1756944000,
  "status": "completed",
  "model": "Google/veo-3.1-fast",
  "url": "https://..."
}
```

A failed job returns `status: "failed"` and an `error` object instead.

### Python

```python
import os
import time

import requests

BASE = "https://inference.nebulablock.com/v1"
headers = {"Authorization": f"Bearer {os.environ['NEBULA_API_KEY']}"}

job = requests.post(
    f"{BASE}/videos/generations",
    headers=headers,
    json={
        "model": "Google/veo-3.1-fast",
        "prompt": "A time-lapse of the Montreal skyline at sunset, cinematic, 35mm",
        "n_seconds": 5,
        "resolution": "720p",
    },
).json()

while True:
    result = requests.get(f"{BASE}/videos/generations/{job['id']}", headers=headers).json()
    if result["status"] in ("completed", "failed"):
        break
    time.sleep(5)

print(result.get("url") or result.get("error"))
```

## Image-to-video

Pass a publicly reachable image as `image_url` and use an `-i2v` model:

```bash
curl -X POST "https://inference.nebulablock.com/v1/videos/generations" \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $NEBULA_API_KEY" \
    --data-raw '{
        "model": "Google/veo-3.1-fast-i2v",
        "prompt": "Slow push-in, leaves drifting across the frame",
        "image_url": "https://example.com/still.jpg",
        "n_seconds": 5
    }'
```

Omitting `image_url` on an `-i2v` model returns `400` with code `missing_parameter`.

## Cost and credit

Video jobs are priced before they run, and the estimate is returned as `estimated_cost` on submission. If your balance cannot cover the estimate, the request is rejected with `402` and code `insufficient_credits` — nothing is queued and nothing is charged.

For Veo, generated audio and higher resolutions increase the cost. See the [pricing page](https://www.nebulablock.com/pricing/serverless-ai) for current rates.

## See also

* [Videos API reference](/api-reference/inference-api/videos) — every parameter and response field
* [Model Catalog](/products/serverless-inference/model-catalog)
* [Image Generation](/products/serverless-inference/image-generation)


# Embeddings

Turn text into vectors for semantic search and RAG with Nebula Block's embedding models.

Embedding models are machine learning models that convert data (such as text, images, or code) into dense numerical vectors in a continuous space. These vectors, called embeddings, capture the semantic relationships between different pieces of data, enabling efficient comparison and retrieval.

## Models available

| Model                   | Model ID                  | Notes                                                                   |
| ----------------------- | ------------------------- | ----------------------------------------------------------------------- |
| Qwen3-Embedding-8B 🇨🇦 | `Qwen/Qwen3-Embedding-8B` | Strong multilingual and code support, top MTEB scorer, hosted in Canada |

See the [Model Catalog](/products/serverless-inference/model-catalog#embeddings) for the current list.

## Using the model

### Through the API

This option is to use our API endpoint directly in your projects. Below are some code snippets to get you started!

> **NOTE:** Don't forget to use **your** API key. See the [API Reference](/api-reference/authentication) and the [Overview](/account/api-keys) for more details on authentication.

#### Using cURL

```bash
curl -X POST "https://inference.nebulablock.com/v1/embeddings" \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $NEBULA_API_KEY" \
    --data-raw '{
      "model":"Qwen/Qwen3-Embedding-8B",
      "input":[ 
            "Bananas are berries, but strawberries are not, according to botanical classifications.",  
            "The Eiffel Tower in Paris was originally intended to be a temporary structure." 
        ] 
    }'
```

#### Using Python

```python
import requests 
import os

url = "https://inference.nebulablock.com/v1/embeddings" 

headers = {  
    "Content-Type": "application/json",  
    "Authorization": f"Bearer {os.environ.get('NEBULA_API_KEY')}" 
} 

data = {
    "model":"Qwen/Qwen3-Embedding-8B",
    "input":[ 
        "Bananas are berries, but strawberries are not, according to botanical classifications.", 
        "The Eiffel Tower in Paris was originally intended to be a temporary structure." 
    ] 
}

response = requests.post(url, headers=headers, json=data) 
print(response.json())
```

#### Using JavaScript

```javascript
const url = 'https://inference.nebulablock.com/v1/embeddings';

const headers = {
    "Content-Type": "application/json",
    "Authorization": `Bearer ${process.env.NEBULA_API_KEY}`
};

const data = {
    "model": "Qwen/Qwen3-Embedding-8B",
    "input": [
        "Bananas are berries, but strawberries are not, according to botanical classifications.",
        "The Eiffel Tower in Paris was originally intended to be a temporary structure."
    ]
};

fetch(url, {
    method: 'POST',
    headers: headers,
    body: JSON.stringify(data)
})
    .then(response => response.json())
    .then(data => {
        console.log(JSON.stringify(data, null, 2));
    })
    .catch(error => console.error('Error:', error));
```

#### Selecting a model

Pass the model ID from the table above as the `model` field.

#### Response Example

A successful response body will return the embeddings in this format:

```json
{
    "model": "Qwen/Qwen3-Embedding-8B",
    "data": [
        
      {
            "embedding": [
                -0.373046875,
                ..., 
                0.248046875
            ],
            "index": 0,
            "object": "embedding"
        },
        {
            "embedding": [
                -0.50390625,
                ...,
                0.01409912109375
            ],
            "index": 1,
            "object": "embedding"
        }
    ],
    "object": "list",
    "usage": {
        "completion_tokens": 0,
        "prompt_tokens": 33,
        "total_tokens": 33,
        "completion_tokens_details": null,
        "prompt_tokens_details": null
    }
}
```

> **NOTE:** Notice that there are 2 embeddings, each with its own index number. These embeddings correspond to the given input sentences, of which there are 2. You can choose how many sentences to create embeddings for, this is just an example.

For every parameter and response field, see the [Embeddings API reference](/api-reference/inference-api/embeddings).

## See also

* [Reranking](/products/serverless-inference/reranking) — reorder retrieved documents before sending them to a model
* [Embeddings API reference](/api-reference/inference-api/embeddings)
* [Model Catalog](/products/serverless-inference/model-catalog)


# Reranking

Reorder retrieved documents by relevance with Nebula Block's reranking models, the second stage of a RAG pipeline.

A reranker scores how relevant each document is to a query. It is the second stage of a typical retrieval pipeline: use [embeddings](/products/serverless-inference/embeddings) to pull back a few dozen candidates cheaply, then rerank them to put the best ones on top before you spend tokens sending them to a model.

## Models available

| Model                   | Model ID                  | Notes                                           |
| ----------------------- | ------------------------- | ----------------------------------------------- |
| BGE-reranker-v2-m3 🇨🇦 | `BAAI/bge-reranker-v2-m3` | Multilingual, 568M parameters, hosted in Canada |

See the [Model Catalog](/products/serverless-inference/model-catalog#reranking) for the current list.

## Rerank documents

```bash
curl -X POST "https://inference.nebulablock.com/v1/rerank" \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $NEBULA_API_KEY" \
    --data-raw '{
        "model": "BAAI/bge-reranker-v2-m3",
        "query": "How do I rent a GPU by the hour?",
        "documents": [
            "Object Storage is an S3-compatible service for datasets and checkpoints.",
            "GPU instances are billed hourly and can be deployed in minutes from the console.",
            "Tier 3 requires a $10 deposit."
        ],
        "top_n": 2
    }'
```

The response ranks the documents by `relevance_score`, highest first, with `index` pointing back at the position in the `documents` array you sent:

```json
{
  "id": "rerank-...",
  "results": [
    { "index": 1, "relevance_score": 0.98 },
    { "index": 2, "relevance_score": 0.41 }
  ]
}
```

### Python

```python
import os

import requests

response = requests.post(
    "https://inference.nebulablock.com/v1/rerank",
    headers={
        "Content-Type": "application/json",
        "Authorization": f"Bearer {os.environ['NEBULA_API_KEY']}",
    },
    json={
        "model": "BAAI/bge-reranker-v2-m3",
        "query": "How do I rent a GPU by the hour?",
        "documents": documents,
        "top_n": 5,
    },
)

for hit in response.json()["results"]:
    print(hit["relevance_score"], documents[hit["index"]])
```

## Using it in a RAG pipeline

1. Embed your corpus once with [Embeddings](/products/serverless-inference/embeddings) and store the vectors.
2. At query time, embed the query and retrieve the top 25–100 candidates by vector similarity.
3. Rerank those candidates and keep the top 3–5.
4. Put only those into the prompt you send to [Chat Completions](/products/serverless-inference/text-generation).

Reranking is far cheaper than sending every candidate to a large model, and it usually improves answer quality more than swapping in a bigger generation model does.

## See also

* [Rerank API reference](/api-reference/inference-api/rerank)
* [Embeddings](/products/serverless-inference/embeddings)
* [Model Catalog](/products/serverless-inference/model-catalog)


# GPU Cloud

Rent NVIDIA B300, B200, H200, H100, A100, L40S and RTX GPUs by the hour across Canada, the US, and Europe.

Rent GPU and CPU compute by the hour for training, fine-tuning, inference, rendering, and simulation. Pick your hardware and OS image, attach an SSH key, and the machine is reachable in minutes.

## Hardware

| GPU                    | Typical use                                                     |
| ---------------------- | --------------------------------------------------------------- |
| **NVIDIA B300 / B200** | Frontier-scale training and inference on Blackwell              |
| **NVIDIA H200**        | Large-model training and high-throughput inference              |
| **NVIDIA H100**        | Large-scale training, available as VM, container, or bare metal |
| **NVIDIA A100**        | AI/ML training and data analytics                               |
| **NVIDIA L40 / L40S**  | Cost-effective inference and graphics workloads                 |
| **NVIDIA RTX series**  | Budget-friendly rendering, visualization, and smaller jobs      |

Configurations run from a single GPU up to 8-GPU nodes (10 in some regions). Availability changes constantly — the [Deploy](https://console.nebulablock.com/deploy) page in the console shows what is in stock right now, and so does [List Products](/api-reference/platform-api/list-products).

How much you can run at once is capped by your account's [hourly spending limit](/getting-started/get-started/spending-limits). New accounts start above the price of the dearest single-GPU configuration, so any of those can be launched immediately; multi-GPU nodes need a limit that has grown with your payment history, or an increase requested from the billing page — usually granted within a few hours.

## Regions

Instances are available in **Canada**, the **United States**, **Finland**, **France**, and **Norway**. Canadian capacity is what backs [Sovereign AI Compute](https://www.nebulablock.com/ai-sovereign-compute) for workloads with data-residency requirements.

## Form factors

* **Virtual machines** — the default, available across every region and GPU type.
* **Containers** — lighter-weight, for workloads that do not need a full VM.
* **Bare metal** — dedicated hardware with no hypervisor, offered on H100.

## Key features

* **Secure access.** SSH key authentication, or a generated username and password where a configuration does not support keys.
* **Firewall rules.** Manage per-instance rules from the console or the [Platform API](/api-reference/platform-api/list-products/firewall-rules). Not available on every configuration — check `firewall_supported` on the instance first.
* **Lifecycle control.** Start, stop, reboot, and delete instances from the console or the API.
* **High-speed networking.** Dedicated bandwidth for moving large datasets in and out.

## Access and billing

* **Tier requirement:** CPU instances need Tier 2, GPU instances need Tier 3 (a $10 deposit). See [Tiers and Rate Limits](/account/tiers-and-limits).
* **Billing:** hourly, deducted from your credit balance for as long as the instance exists.
* Rates per configuration are on the [pricing page](https://www.nebulablock.com/pricing/gpu-instances).

> **Important:** Instances are billed while they exist, and are deleted automatically if your credit balance runs out. Turn on auto-pay for anything long-running — see [Billing](/getting-started/get-started/billing).

## See also

* [Quickstart](/products/gpu-cloud/quickstart)
* [SSH Keys](/products/gpu-cloud/ssh-keys)
* [Instances API](/api-reference/platform-api/list-products)
* [Glossary](/resources/glossary)


# Quickstart

Deploy your first Nebula Block GPU instance: pick hardware and a region, attach an SSH key, and connect.

Deploy your first GPU instance.

## Before you start

* [Create an account](https://console.nebulablock.com/register), or sign in with Google.
* **Deposit $10 to reach Tier 3**, which is what unlocks GPU instances. CPU instances need Tier 2 ($5). See [Tiers and Rate Limits](/account/tiers-and-limits).
* [Add an SSH key](/products/gpu-cloud/ssh-keys) so you can log into the instance once it is running.

## Create a GPU Instance

Open [**Deploy**](https://console.nebulablock.com/deploy) in the console.

* Choose a Location
  * Canada, the United States, Finland, France, or Norway. Pick the region closest to you, or the one your data-residency requirements call for.
* Select Hardware Configuration
  * Choose from the available GPU options:

    * NVIDIA B300 / B200: Blackwell-class training and inference.
    * NVIDIA H200: Large-model training and high-throughput inference.
    * NVIDIA H100: Large-scale training, also offered as container and bare metal.
    * NVIDIA A100: AI/ML training and data analytics.
    * NVIDIA L40 / L40S: Cost-effective inference and graphics workloads.
    * NVIDIA RTX series: Budget-friendly rendering and smaller jobs.

    Configurations run from a single GPU up to 8-GPU nodes, and 10 in some regions. What is in stock varies by region — the [Deploy](https://console.nebulablock.com/deploy) page shows current availability.
* Choose an Operating System/Image
* Select an SSH Public Key (if applicable)
  * Create or select an existing SSH public key for secure access to the instance.
  * Note that some instances may not support SSH Public Keys yet, in which case a secure username and password will be provided to you.
* Set a Server Name
  * Assign a meaningful name to your instance for easy identification.
* Deploy
  * Review your configuration and click "Deploy". Your instance will be provisioned and ready within minutes.

## Connect to Your GPU Instance

**SSH Key Authentication**

Once your instance is running, connect to it using SSH:

```bash
ssh -i /path/to/your/private/key username@instance-ip
```

* Replace `/path/to/your/private/key` with the path to your private SSH key.
* Replace `username` with the username of your instance, and replace `instance-ip` with the public IP Address of your instance. You can find the username and Public IP Address information in your instance detail page.

**Password Authentication**

Once your instance is running, connect to it using SSH:

```bash
ssh username@instance-ip
```

* You'll then be prompted for your password. Simply enter it and press Enter.
* Replace `username` with the username of your instance, and replace `instance-ip` with the public IP Address of your instance.
* You can find the username, password and Public IP Address in your instance detail page.

## Manage Your Instance

* Open [**Instances**](https://console.nebulablock.com/instance) in the console to see everything you have running, and click through for an instance's details, credentials, and firewall rules.
* Use the controls there to power on, power off, reboot, or terminate an instance. Some configurations support only terminate.
* The same actions are available through the API — see [Instances](/api-reference/platform-api/list-products/list-instances).

> **Important:** An instance is billed for as long as it exists, whether or not it is powered on. Terminate anything you are finished with, and keep an eye on your balance — instances are deleted automatically if you run out of credit.

## See also

* [GPU Cloud](/products/gpu-cloud)
* [SSH Keys](/products/gpu-cloud/ssh-keys)
* [Billing](/getting-started/get-started/billing)


# SSH Keys

Generate an SSH key pair, add it to your Nebula Block account, and use it to log into your instances.

SSH keys authenticate you to your instances. They are more secure than passwords, and Nebula Block needs one on file before it can hand you a machine you can log into. Managing them is free — add as many as you like.

## Generate a key pair

If you do not already have one:

```bash
ssh-keygen -t ed25519 -C "you@example.com"
```

This writes a private key to `~/.ssh/id_ed25519` and a public key to `~/.ssh/id_ed25519.pub`. **Only the public key is uploaded to Nebula Block** — never share the private half.

## Add a key to your account

1. Sign in and open [**SSH Keys**](https://console.nebulablock.com/sshKey) in the console.
2. Click to add a key, give it a name, and paste the contents of your `.pub` file.
3. Save. The key is then selectable whenever you deploy an instance.

You can do the same through the API — see [Create SSH Key](/api-reference/platform-api/list-ssh-keys/create-ssh-key).

```bash
cat ~/.ssh/id_ed25519.pub
```

## Use a key

Select the key when you create an instance. Once the instance is running, connect with the matching private key:

```bash
ssh -i ~/.ssh/id_ed25519 username@instance-ip
```

The username and public IP are on the instance's detail page in the console.

> **Note:** Some configurations do not support SSH keys yet. For those, a username and password are generated for you and shown on the instance detail page.

## Manage keys

|                                                                            |                         |
| -------------------------------------------------------------------------- | ----------------------- |
| [List SSH Keys](/api-reference/platform-api/list-ssh-keys)                 | `GET /ssh-keys/`        |
| [Create SSH Key](/api-reference/platform-api/list-ssh-keys/create-ssh-key) | `POST /ssh-keys/`       |
| [Rename SSH Key](/api-reference/platform-api/list-ssh-keys/rename-ssh-key) | `PUT /ssh-keys/{id}`    |
| [Delete SSH Key](/api-reference/platform-api/list-ssh-keys/delete-ssh-key) | `DELETE /ssh-keys/{id}` |

Deleting a key from your account does not remove it from instances that are already running.

## See also

* [GPU Cloud Quickstart](/products/gpu-cloud/quickstart)
* [Glossary](/resources/glossary)


# Object Storage

S3-compatible object storage for datasets, checkpoints, and model outputs, with workspaces, buckets, and usage reporting.

S3-compatible object storage for datasets, checkpoints, and generated media. Because it speaks the S3 protocol, the tools you already use — `s3cmd`, `boto3`, the AWS SDKs — work against it unchanged.

## How it is organised

* A **workspace** is the top-level container. Creating one issues an S3 access key pair that your tools authenticate with, and it is ready to use immediately.
* **Buckets** live inside a workspace and hold your objects. They are private by default and can be switched to public.

> **Note:** The platform prefixes new bucket names — a bucket you create as `checkpoints` in workspace `research` becomes something like `u-2f36933d-research.checkpoints`. That prefixed name is what `s3cmd` and the S3 SDKs see, so take it from the console's **Buckets** tab rather than assuming the name you typed. Buckets created before the storage backend was migrated keep their original names.

## Key features

* **S3-compatible API.** Point existing S3 tooling at your workspace endpoint.
* **Console management.** Create workspaces and buckets, upload and delete files, and toggle bucket privacy from [Object Storage](https://console.nebulablock.com/object-storage) in the console.
* **Platform API.** Automate the same operations — see [Object Storage API](/api-reference/platform-api/list-workspaces).
* **Usage reporting.** Storage and transfer usage broken down over 24 hours, 7 days, and 30 days.
* **Key rotation.** Regenerate a workspace's access key pair when you need to.

## Prerequisites

* A [Nebula Block account](https://console.nebulablock.com/register)
* Credit on your account — Standard workspaces store data free and bill outgoing traffic per GB

## Getting started

|                                          |                                                                        |
| ---------------------------------------- | ---------------------------------------------------------------------- |
| Create a workspace and your first bucket | [Quickstart](/products/object-storage/quickstart)                      |
| Set up `s3cmd` on Linux or macOS         | [s3cmd on Linux and macOS](/products/object-storage/s3cmd-linux-macos) |
| Set up `s3cmd` on Windows                | [s3cmd on Windows](/products/object-storage/s3cmd-windows)             |
| Use the AWS SDK for Python               | [Python SDK](/products/object-storage/sdk-python)                      |
| Use the AWS SDK for Go                   | [Go SDK](/products/object-storage/sdk-go)                              |
| Use the AWS SDK for Java                 | [Java SDK](/products/object-storage/sdk-java)                          |

## Pricing and billing

Object storage comes in three tiers, priced per the console's [create form](https://console.nebulablock.com/create-object-storage):

| Tier            | Stored data     | Notes                                       |
| --------------- | --------------- | ------------------------------------------- |
| **Standard**    | Free            | Durable, high-capacity storage. The default |
| **Performance** | $0.015/GB/month | Low-latency, for frequent access            |
| **Accelerated** | $0.02/GB/month  | For write-intensive workloads               |

Outgoing traffic is billed at $0.01/GB on all tiers; incoming traffic is included. Availability varies — a tier can show as out of stock.

Rates for a workspace you already have are on its **Overview** tab. Object storage is not covered by the public pricing page, so treat the console as authoritative.

Usage is metered hourly. See [Get Storage Usage](/api-reference/platform-api/list-workspaces/get-usage) to read stored volume and transfer programmatically.

## See also

* [Object Storage API](/api-reference/platform-api/list-workspaces)
* [Glossary](/resources/glossary)


# Quickstart

Create your first Nebula Block object storage workspace and bucket, then upload and delete files.

## Starting Your Object Storage

1. Navigate to the **Object Storage** tab **(1)**, and click **Create** **(2)**.

   ![1.1](https://540120125-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FXZhubbpeVAa2uzXxQcny%2Fuploads%2Fgit-blob-7380fb7eefc8888b8640327248de949eb70379a3%2F1.jpg?alt=media)
2. Select your configuration, a **unique name** and click **Create**.

   > **Note:** The name of object storage should not contain a space.

   ![1.2](https://540120125-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FXZhubbpeVAa2uzXxQcny%2Fuploads%2Fgit-blob-eee9f0e84bcc346d80affed77d00c62fd33b8948%2F2.jpg?alt=media)
3. Your new storage deployment should now appear in the list. Click **View** to check the details of the object storage

   ![1.3](https://540120125-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FXZhubbpeVAa2uzXxQcny%2Fuploads%2Fgit-blob-01b8052ed70b67e8d8324a7b1482b8446a72a512%2F3.jpg?alt=media)
4. The object storage information contains your usage status, billing info and s3 keys info. You can use the key and s3cmd to access your object storage

   ![1.4](https://540120125-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FXZhubbpeVAa2uzXxQcny%2Fuploads%2Fgit-blob-b7dcc57d7ffc4073b14bd0327f2208b6645f30bf%2F5.jpg?alt=media) [s3cmd set up for Linux/macOS](/products/object-storage/s3cmd-linux-macos) [s3cmd set up for Windows](/products/object-storage/s3cmd-windows)

> **Note:** Storage names are account-unique.

## Create Your Bucket

1. Navigate to the **Buckets** tab **(1)**, and then click **Create Bucket** **(2)**.

   ![2.1](https://540120125-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FXZhubbpeVAa2uzXxQcny%2Fuploads%2Fgit-blob-7c1d151c67163d70e031905951e81bfb8e6bdf59%2F6.jpg?alt=media)
2. Type in your bucket name.

   ![2.2](https://540120125-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FXZhubbpeVAa2uzXxQcny%2Fuploads%2Fgit-blob-606f19dcb677de347d0b9c9d2e0a9bbea81683b2%2F7.jpg?alt=media)

   > **Note:** Bucket names must be globally unique. If s3cmd fails to create one, try another name.\
   > Bucket name should follow these rules:
   >
   > * Only lowercase letters (`a-z`), numbers (`0-9`), and hyphens (`-`) are allowed
   > * Must begin with a letter or number
   > * Length must be between **3 to 63 characters**
   > * Cannot contain uppercase letters, underscores (`_`), spaces, or other special characters
   > * Avoid starting or ending with a hyphen (`-`)
3. Once the bucket name meets the requirements, it will appear in the list below.

   ![2.3](https://540120125-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FXZhubbpeVAa2uzXxQcny%2Fuploads%2Fgit-blob-47454cb6d1d11f7fb554f5c9a7c49556c113ef0e%2F8.jpg?alt=media)

## Upload Your File

1. In the bucket view, you can upload files by clicking the **Upload** button **(1)**. Next, click the **Upload File** button **(2)** to select a file from your local system. Finally, click the **Upload** button **(3)** to upload the selected file to your bucket.

   ![3.1](https://540120125-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FXZhubbpeVAa2uzXxQcny%2Fuploads%2Fgit-blob-2542714dd21c2a24649b53a7a019f26246dbd05b%2F9.jpg?alt=media)

   > **Note:** The file size must not exceed **50 MB**.\
   > Folder and multiple file upload features are coming soon.\
   > For now, please use **s3cmd** to upload entire folders.
2. File has been uploaded successfully.

   ![3.2](https://540120125-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FXZhubbpeVAa2uzXxQcny%2Fuploads%2Fgit-blob-d3fd610442f9f4dec8c9dfb037f7d50d5854b634%2F10.jpg?alt=media)
3. If your bucket already contains folders, you can customize the upload path for your file. Select **Path**, then choose the folder where you want to upload the file.

   ![3.3](https://540120125-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FXZhubbpeVAa2uzXxQcny%2Fuploads%2Fgit-blob-20936fb5755bc709d8c36a320c183ef38845854f%2F11.jpg?alt=media)

## Delete Your File

1. You can delete multiple files and folders in your bucket at once. Select the files and folders **(1)**, then click the **Delete** button.\
   The selected items will be permanently deleted.

   ![4.1](https://540120125-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FXZhubbpeVAa2uzXxQcny%2Fuploads%2Fgit-blob-af3d65c3fb1728d0ede9c35a1465a0eadf9dc6a8%2F12.jpg?alt=media) ![4.1](https://540120125-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FXZhubbpeVAa2uzXxQcny%2Fuploads%2Fgit-blob-86871631fe0299da42746dc8e44b3f84ba039c24%2F13.jpg?alt=media) ![4.1](https://540120125-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FXZhubbpeVAa2uzXxQcny%2Fuploads%2Fgit-blob-52e6b427b3ce1aaa513aa36e0a20ea4511536504%2F14.jpg?alt=media)

## Delete Your Bucket

1. In the list of your buckets, you can delete a bucket by clicking the **Delete** button.

   ![5.1](https://540120125-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FXZhubbpeVAa2uzXxQcny%2Fuploads%2Fgit-blob-40cdcb749e086fd1e3df08a250773fba2f196084%2F15.jpg?alt=media) ![5.2](https://540120125-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FXZhubbpeVAa2uzXxQcny%2Fuploads%2Fgit-blob-f2893532c1c8e37fc0162e93b7a44ea94abe2808%2F16.jpg?alt=media) ![5.3](https://540120125-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FXZhubbpeVAa2uzXxQcny%2Fuploads%2Fgit-blob-859db1d50e0d8967e2315eab2e7b86ec82455844%2F17.jpg?alt=media)

   > **Warning:** Deleting a bucket will permanently remove the bucket along with all its contents. This action cannot be undone.

## Delete Your Object Storage

To remove your storage:

1. Go to the **Object Storage** tab.
2. Click **Delete** on the deployment you want to remove.

   ![6.1](https://540120125-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FXZhubbpeVAa2uzXxQcny%2Fuploads%2Fgit-blob-4db06b4217b2f41567021c0e0ab98972b0f71a42%2F18.jpg?alt=media)
3. Confirm the deletion.

   ![6.2](https://540120125-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FXZhubbpeVAa2uzXxQcny%2Fuploads%2Fgit-blob-617950a035b8add3d00ce0ec15c848b2c68e71f3%2F19.jpg?alt=media)
4. Use the **Active** filter to view object storage that are **Ready** or **Deleted**, **Disabled**.

   ![6.3](https://540120125-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FXZhubbpeVAa2uzXxQcny%2Fuploads%2Fgit-blob-998f9506a2e6e1c84615b803816b1723ae3bd6ad%2F4.jpg?alt=media)

## Billing

Your deployment shows:

* Storage Usage: How much data you're storing.
* Bandwidth Usage: How much data has been transferred out.
* Current Charges: The total charges incurred so far, calculated by a rate on your storage usage and a rate on your bandwidth usage.

The values are updated hourly. To view pricing:

* Go to your storage deployment's **Details** page.

![7.1](https://540120125-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FXZhubbpeVAa2uzXxQcny%2Fuploads%2Fgit-blob-f67b0bd964ec52055ee54f04593b9d04b3bda989%2F5.png?alt=media)

* Or check the pricing when selecting your configuration

![7.2](https://540120125-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FXZhubbpeVAa2uzXxQcny%2Fuploads%2Fgit-blob-6d344960c268ff7d6c4e629d1748772003e10544%2F6.png?alt=media)


# s3cmd on Linux and macOS

Configure s3cmd on Linux or macOS to manage Nebula Block object storage from the command line.

`s3cmd` is the quickest way to work with your buckets from a terminal. Nebula Block object storage speaks the S3 API, so `s3cmd` works against it unchanged once it is pointed at your workspace's endpoint.

> **Tip:** The console generates this configuration for you, already filled in with your endpoint and access keys. Open your workspace under [Object Storage](https://console.nebulablock.com/object-storage), click **View**, and go to the **s3cmd** tab. Copying from there avoids transcription mistakes — the steps below are the same thing, explained.

## 1. Install s3cmd

```bash
# macOS
brew install s3cmd

# Debian / Ubuntu
sudo apt-get install -y s3cmd

# RHEL / CentOS / Fedora
sudo yum install -y s3cmd

# Cross-platform (Python)
pip install s3cmd
```

## 2. Create `~/.s3cfg`

Rather than working through `s3cmd --configure` interactively, write the config file directly. Save this as `~/.s3cfg`, substituting your own keys and hostname:

```ini
[default]
access_key = YOUR_ACCESS_KEY
secret_key = YOUR_SECRET_KEY
host_base = s3-ca-east.nebulablock.com:443
host_bucket = s3-ca-east.nebulablock.com:443
use_https = True
signature_v2 = False
check_ssl_certificate = True
check_ssl_hostname = True
```

Where these values come from:

| Setting                    | Where to find it                                                                                           |
| -------------------------- | ---------------------------------------------------------------------------------------------------------- |
| `access_key`, `secret_key` | The **S3 Credentials** panel on your workspace's **Overview** tab. Click the eye icon to reveal the secret |
| `host_base`, `host_bucket` | The **Hostname** shown in that same panel, with `:443` appended                                            |

Two details worth understanding rather than copying blindly:

* **`host_bucket` matches `host_base` and has no `%(bucket)s` placeholder.** That selects path-style addressing (`https://host/bucket/key`). Virtual-hosted style works too, but path-style is what the console's snippet uses and it avoids per-bucket DNS concerns.
* **`signature_v2 = False`** keeps `s3cmd` on AWS Signature Version 4. Do not switch this to `True`.

> **Important:** Your secret key is a credential. Keep `~/.s3cfg` readable only by you (`chmod 600 ~/.s3cfg`), and do not commit it.

## 3. Verify the connection

Listing your buckets confirms both the credentials and the endpoint:

```bash
s3cmd ls
```

If this returns your buckets — or nothing at all, when you have not created any yet — you are configured correctly. An error here almost always means a wrong hostname or a mistyped key.

## Working with buckets

```bash
s3cmd mb s3://YOUR-BUCKET       # create a bucket
s3cmd ls                        # list buckets
s3cmd du s3://YOUR-BUCKET       # show bucket size
s3cmd rb s3://YOUR-BUCKET       # delete a bucket (must be empty)
```

## Working with objects

```bash
s3cmd put local-file.txt s3://YOUR-BUCKET/          # upload one file
s3cmd get s3://YOUR-BUCKET/local-file.txt .         # download one file
s3cmd ls s3://YOUR-BUCKET/                          # list objects
s3cmd sync ./local-folder s3://YOUR-BUCKET/         # sync a folder up
s3cmd sync s3://YOUR-BUCKET/ ./local-folder         # sync a folder down
s3cmd del s3://YOUR-BUCKET/local-file.txt           # delete an object
```

`s3cmd sync` is the right tool for datasets and checkpoints — it transfers only what changed, and it handles large files far better than uploading through the console or the Platform API.

## Generate a presigned URL

Hand out a short-lived URL that anyone can use to download a private object, with no credentials:

```bash
s3cmd signurl s3://YOUR-BUCKET/local-file.txt $(($(date +%s) + 3600))
```

The trailing number is an absolute expiry timestamp — the example above is one hour from now.

## See also

* [s3cmd on Windows](/products/object-storage/s3cmd-windows)
* [Python SDK](/products/object-storage/sdk-python)
* [Object Storage](/products/object-storage)


# s3cmd on Windows

Install and configure s3cmd on Windows to manage Nebula Block object storage.

> **Tip:** The console generates a ready-to-paste `~/.s3cfg` for you, filled in with your endpoint and access keys. Open your workspace under [Object Storage](https://console.nebulablock.com/object-storage), click **View**, and go to the **s3cmd** tab. If you use it, you can skip the interactive `s3cmd --configure` walkthrough below and save the block it gives you as `%USERPROFILE%\.s3cfg`. See [s3cmd on Linux and macOS](/products/object-storage/s3cmd-linux-macos) for what each setting means.

## 1. Install s3cmd

### Step 1: Check Python Installation

Ensure Python is installed by running:

```sh
python --version
```

If Python is not installed, download and install it from [Python Official Website](https://www.python.org/downloads/).

### Step 2: Upgrade pip

Run the following command to upgrade `pip`:

```sh
python -m pip install --upgrade pip
```

### Step 3: Install s3cmd

Run the following command to install `s3cmd`:

```sh
pip install s3cmd
```

### Step 4: Ensure s3cmd is Executable

By default, Windows may recognize `s3cmd` as a file without an extension instead of a Python script. Navigate to the following path:

```
C:\Users\<Username>\AppData\Local\Programs\Python\PythonXX\Scripts\
```

* If `s3cmd` is present without a `.py` extension, rename it to `s3cmd.py`.
* Add this location to your system environment variables (`Path`).

### Step 5: Verify Installation

Run:

```sh
s3cmd --version
```

If `s3cmd` does not execute correctly, open the `s3cmd` file and ensure the first two lines are:

```
#!C:\Python310\python.exe
#coding: utf-8 -
```

If necessary, run `s3cmd` using:

```sh
python C:\Python310\Scripts\s3cmd.py --version
```

Alternatively, create a `s3cmd.bat` file in the same directory as `s3cmd.py` with the following content:

```
@echo off
python C:\Python310\Scripts\s3cmd %*
```

Then, retry running:

```sh
s3cmd --version
```

## 2. Configure s3cmd

Run:

```sh
s3cmd --configure
```

You will be prompted to enter the following details:

```
Access Key: YOUR_ACCESS_KEY
Secret Key: YOUR_SECRET_KEY
Default Region: US
S3 Endpoint: HOST_NAME //Use the Hostname from the Details page.
DNS-style bucket+hostname: HOST_NAME //Use the Hostname from the Details page.
Encryption password: (press Enter to pass)
Path to GPG program: (press Enter to pass)
Use HTTPS protocol: No
HTTP Proxy server name: (press Enter to pass)
```

Test access with supplied credentials:

```
Test access with supplied credentials? [Y/n]: Y
```

If the connection is successful, you will see:

```
Please wait, attempting to list all buckets...
Success. Your access key and secret key worked fine :-)
```

Save settings:

```
Save settings? [y/N]: y
```

Your configuration will be saved at:

```
C:\Users\<Username>\AppData\Roaming\s3cmd.ini
```

## 3. Usage Examples

### List Buckets

```sh
s3cmd ls
```

### Create a Bucket

```sh
s3cmd mb s3://my-bucket-name
```

### Delete an Empty Bucket

```sh
s3cmd rb s3://my-bucket-name
```

### List Files in a Bucket

```sh
s3cmd ls s3://my-bucket-name
```

### Upload a File to a Bucket

```sh
s3cmd put <local_file_path> s3://my-bucket-name/<remote_file_name>
```

Example:

```sh
s3cmd put C:\Users\Username\Desktop\files\mv-test.mp4 s3://test-bucket/upload_test.mp4
```

### Upload a folder to a Bucket

```sh
s3cmd put --recursive <local_file_path> s3://my-bucket-name
```

Example:

```sh
s3cmd put --recursive C:\Users\Username\Desktop\files s3://test-bucket
```

### Download a File from a Bucket

```sh
s3cmd get s3://my-bucket-name/<remote_file_name> <local_file_path>
```

Example:

```sh
s3cmd get s3://test-bucket/upload_test.mp4 C:\Users\Username\Desktop\mv_download.mp4
```

### Delete a File

```sh
s3cmd del s3://my-bucket-name/<remote_file_name>
```

### Batch Upload Files Example

```sh
s3cmd put C:\Users\Username\Desktop\video1.mp4 C:\Users\Username\Desktop\video2.mp4 C:\Users\Username\Desktop\video3.mp4 s3://test-bucket/
```

### Batch Download Files Example

```sh
s3cmd sync s3://test-bucket/video1.mp4 s3://test-bucket/video2.mp4 s3://test-bucket/video3.mp4 C:\Users\Username\Desktop\download_temp\
```

or

```sh
s3cmd get s3://test-bucket/video1.mp4 s3://test-bucket/video2.mp4 s3://test-bucket/video3.mp4 C:\Users\Username\Desktop\download_temp\
```

### Batch Delete Files Example

```sh
s3cmd del s3://test-bucket/video1.mp4 s3://test-bucket/video2.mp4 s3://test-bucket/video3.mp4
```


# Python SDK

Use boto3, the AWS SDK for Python, against Nebula Block S3-compatible object storage.

This example demonstrates how to connect to Nebula Block (an S3-compatible service) and perform basic operations like listing buckets, uploading, downloading, and generating a presigned URL using the AWS SDK for Python [`boto3`](https://boto3.amazonaws.com/v1/documentation/api/latest/index.html).

## Prerequisites

Before running the code, ensure you have the following:

1. Create an object storage bucket on the [Nebula Block](https://console.nebulablock.com/object-storage) platform, then navigate to the corresponding page to obtain the storage access credentials. ![1.1](https://540120125-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FXZhubbpeVAa2uzXxQcny%2Fuploads%2Fgit-blob-c42237c1bf9d65cc49a27185dad1d4ac42f74d31%2F7.png?alt=media)
2. **Python** installed.
3. **boto3** and **python-dotenv** libraries installed. You can install them using pip:

   ```bash
   pip install boto3 python-dotenv
   ```
4. Create a `.env` file with your Nebula Block credentials:

   ```ini
   NEBULA_ACCESS_KEY=YOUR_ACCESS_KEY  #Use the Access Key from the Details page.
   NEBULA_SECRET_KEY=YOUR_SECRET_KEY  #Use the Secret Key from the Details page.
   NEBULA_ENDPOINT=YOUR_ENDPOINT_URL  #Use the Hostname from the Details page.
   NEBULA_REGION=YOUR_REGION          #Optional, default None.
   NEBULA_BUCKET=YOUR_BUCKET_NAME
   ```

## Python Code

### Common Usage Examples

#### Create/Delete Bucket Demo

```python
import os
import sys
import logging
import boto3
from botocore.client import Config
from dotenv import load_dotenv

# Nebula Block configuration
NEBULA_CONFIG = {
    'aws_access_key_id': os.getenv('NEBULA_ACCESS_KEY'),
    'aws_secret_access_key': os.getenv('NEBULA_SECRET_KEY'),
    'endpoint_url': f"https://{os.getenv('NEBULA_ENDPOINT')}", 
    'region_name': os.getenv('NEBULA_REGION'),
    'bucket_name': os.getenv('NEBULA_BUCKET')
}

signature_version = 's3v4' # s3v4 for bucket management, s3 for upload and downloand file

s3_client = boto3.client(
    's3',
    aws_access_key_id=NEBULA_CONFIG['aws_access_key_id'],
    aws_secret_access_key=NEBULA_CONFIG['aws_secret_access_key'],
    endpoint_url=NEBULA_CONFIG['endpoint_url'],
    region_name=NEBULA_CONFIG['region_name'],
    config=Config(signature_version=signature_version)
)

s3_client.create_bucket(Bucket=NEBULA_CONFIG['bucket_name'])
s3_client.list_buckets()
s3_client.delete_bucket(Bucket=NEBULA_CONFIG['bucket_name'])
```

### Upload/Download File Demo

```python
#!/usr/bin/env python3
import os
import sys
import logging
import boto3
from botocore.client import Config
from dotenv import load_dotenv

# Configure logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

# Load environment variables
load_dotenv()

# Nebula Block configuration
NEBULA_CONFIG = {
    'aws_access_key_id': os.getenv('NEBULA_ACCESS_KEY'),
    'aws_secret_access_key': os.getenv('NEBULA_SECRET_KEY'),
    'endpoint_url': f"https://{os.getenv('NEBULA_ENDPOINT')}", 
    'region_name': os.getenv('NEBULA_REGION'),
    'bucket_name': os.getenv('NEBULA_BUCKET')
}

# Create an S3 client
def create_s3_client():
    try:
        s3_client = boto3.client(
            's3',
            aws_access_key_id=NEBULA_CONFIG['aws_access_key_id'],
            aws_secret_access_key=NEBULA_CONFIG['aws_secret_access_key'],
            endpoint_url=NEBULA_CONFIG['endpoint_url'],
            region_name=NEBULA_CONFIG['region_name'],
            config=Config(signature_version='s3')
        )
        return s3_client
    except Exception as e:
        logger.error(f"Error creating S3 client: {e}")
        return None

# Test connection
def test_connection(s3_client):
    try:
        s3_client.list_buckets()
        logger.info("Successfully connected to Nebula Block storage!")
        return True
    except Exception as e:
        logger.error(f"Error connecting to Nebula Block: {e}")
        return False

# Upload a file
def upload_file(s3_client, file_path, object_name=None):
    if object_name is None:
        object_name = os.path.basename(file_path)
    try:
        s3_client.upload_file(file_path, NEBULA_CONFIG['bucket_name'], object_name)
        logger.info(f"File '{file_path}' uploaded successfully as '{object_name}'!")
        return True
    except Exception as e:
        logger.error(f"Error uploading file: {e}")
        return False

# Download a file
def download_file(s3_client, object_name, file_path=None):
    if file_path is None:
        file_path = object_name
    try:
        s3_client.download_file(NEBULA_CONFIG['bucket_name'], object_name, file_path)
        logger.info(f"File '{object_name}' downloaded successfully to '{file_path}'!")
        return True
    except Exception as e:
        logger.error(f"Error downloading file: {e}")
        return False

# List objects in a bucket
def list_objects(s3_client, prefix=None):
    try:
        if prefix:
            response = s3_client.list_objects_v2(Bucket=NEBULA_CONFIG['bucket_name'], Prefix=prefix)
        else:
            response = s3_client.list_objects_v2(Bucket=NEBULA_CONFIG['bucket_name'])

        if 'Contents' in response:
            logger.info(f"Objects in bucket '{NEBULA_CONFIG['bucket_name']}':")
            for obj in response['Contents']:
                logger.info(f"  - {obj['Key']} ({obj['Size']} bytes)")
            return response['Contents']
        else:
            logger.info(f"No objects found in bucket '{NEBULA_CONFIG['bucket_name']}'")
            return []
    except Exception as e:
        logger.error(f"Error listing objects: {e}")
        return []

# Generate a presigned URL
def generate_presigned_url(s3_client, object_name, expiration=3600):
    try:
        url = s3_client.generate_presigned_url(
            'get_object',
            Params={'Bucket': NEBULA_CONFIG['bucket_name'], 'Key': object_name},
            ExpiresIn=expiration
        )
        return url
    except Exception as e:
        logger.error(f"Error generating presigned URL: {e}")
        return None

# Main function
def main():
    if not all(NEBULA_CONFIG.values()):
        logger.error("Missing configuration. Please check your .env file.")
        sys.exit(1)

    s3_client = create_s3_client()
    if not s3_client:
        sys.exit(1)

    if not test_connection(s3_client):
        sys.exit(1)

    test_file_path = 'test_file.txt'
    with open(test_file_path, 'w') as f:
        f.write('This is a test file for Nebula Block storage.')

    if not upload_file(s3_client, test_file_path, 'test_file.txt'):
        os.remove(test_file_path)
        sys.exit(1)

    list_objects(s3_client)

    url = generate_presigned_url(s3_client, 'test_file.txt', expiration=3600)
    if url:
        logger.info(f"Presigned URL (valid for 1 hour): {url}")

    if not download_file(s3_client, 'test_file.txt', 'downloaded_test_file.txt'):
        os.remove(test_file_path)
        sys.exit(1)

    if os.path.exists(test_file_path):
        os.remove(test_file_path)
    if os.path.exists('downloaded_test_file.txt'):
        os.remove('downloaded_test_file.txt')

    logger.info("Nebula Block storage example completed successfully!")

if __name__ == "__main__":
    main()
```

## Explanation

### Steps in the Code

1. **Credentials**: The program uses `boto3.client()` to authenticate with the S3-compatible service using the provided access key and secret key. Ensure to replace `YOUR_ACCESS_KEY` and `YOUR_SECRET_KEY` with your actual credentials.
2. **Client Configuration**: The `boto3.client()` is configured with the endpoint and region of the S3-compatible service. The `signature_version='s3v4'` ensures the use of S3 v4 signature for secure requests.
3. **Test Connection**: Tests if the client can successfully list the buckets to verify the connection.
4. **Create Bucket**: The script attempts to create the specified bucket. If the bucket already exists, it will proceed without error.
5. **Upload a File**: Uploads a test file from the local system to the specified bucket in Nebula Block storage.
6. **Download a File**: Downloads the uploaded test file from Nebula Block storage to the local system to verify successful upload.
7. **List Objects**: Lists all objects in the specified bucket to confirm the file was uploaded.
8. **Presigned URL Generation**: Generates a temporary URL for downloading the uploaded object without needing further authentication.
9. **Cleanup**: Deletes the local temporary test files after completing the demonstration.

## Run the Code

To run the program, simply execute the script as a standard Python application:

```bash
python your_script_name.py
```

Make sure to have the `boto3` and `python-dotenv` libraries installed and your `.env` file properly configured with your Nebula Block credentials.

***

**Note**: Ensure that you keep your access keys secure. Do not hardcode them in production code. Always use environment variables or secret managers.


# Go SDK

Use the AWS SDK for Go against Nebula Block S3-compatible object storage.

This Go program demonstrates how to interact with an S3-compatible service using the AWS SDK for Go. The program lists all available S3 buckets. Please use aws-sdk-go V1 version as follows.

## Prerequisites

To run this program, you'll need:

* Go installed on your machine (<https://golang.org/doc/install>).
* AWS SDK for Go installed. You can get it using:

  ```bash
  go get github.com/aws/aws-sdk-go
  ```
* Access credentials (Access Key ID and Secret Access Key) for the S3-compatible service you are connecting to.

## Code

```go
package main

import (
	"fmt"
	"log"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/credentials"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/s3"
)

func main() {
	// Set the S3 compatible service information
	accessKey := "YOUR_ACCESS_KEY"
	secretKey := "YOUR_SECRET_KEY"
	endpoint := "HOST_NAME" //Use the Hostname from the Details page.
	region := "US"

	// Create a session
	s3Config := &aws.Config{
		Credentials:      credentials.NewStaticCredentials(accessKey, secretKey, ""),
		Endpoint:         aws.String(endpoint),
		Region:           aws.String(region),
		S3ForcePathStyle: aws.Bool(true), // Use path-style instead of virtual host style
	}

	sess, err := session.NewSession(s3Config)
	if err != nil {
		log.Fatalf("Failed to create session: %v", err)
	}

	// Create S3 service client
	svc := s3.New(sess)

	// List all buckets
	fmt.Println("Attempting to list buckets...")
	result, err := svc.ListBuckets(nil)
	if err != nil {
		log.Fatalf("Failed to list buckets: %v", err)
	}

	fmt.Println("Successfully connected! Current buckets:")
	for _, bucket := range result.Buckets {
		fmt.Printf("  - %s
", *bucket.Name)
	}
}
```

## Explanation

1. **Setting up the S3 Configuration:**
   * The program starts by setting the AWS access key, secret key, and endpoint of the S3-compatible service. The region is also set to `us`.
   * `S3ForcePathStyle` is set to `true` to use path-style addressing rather than virtual host style.
2. **Creating a Session:**
   * A new session is created using the configuration parameters. If the session creation fails, the program logs an error and exits.
3. **Listing Buckets:**
   * The program uses the `ListBuckets` API to retrieve all available buckets. If the request is successful, it prints out the names of the buckets.

## Running the Program

1. Save the above code to a file, for example, `main.go`.
2. Run the program using the following command:

   ```bash
   go run main.go
   ```
3. The output will display the names of the S3 buckets.

### Example Output

```
Attempting to list buckets...
Successfully connected! Current buckets:
  - my-bucket-name-1
  - my-bucket-name-2
  - my-bucket-name-3
```

## Notes

* Make sure your AWS credentials (Access Key and Secret Key) are correctly set.
* The program will list the buckets available at the specified S3-compatible service endpoint.


# Java SDK

Use the AWS SDK for Java against Nebula Block S3-compatible object storage.

This example demonstrates how to connect to an S3 compatible service and list all buckets using the AWS SDK for Java.

## Prerequisites

Before running the code, ensure you have the following:

1. **Java Development Kit (JDK)** installed.
2. **AWS SDK for Java** added as a dependency.
3. Replace `YOUR_ACCESS_KEY` and `YOUR_SECRET_KEY` with your actual AWS credentials.

## Maven Dependency

If you're using Maven, you need to add the following dependency in your `pom.xml`:

```xml
<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-java-sdk-s3</artifactId>
    <version>1.12.664</version>
</dependency>
```

## Java Code

```java
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.client.builder.AwsClientBuilder;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.Bucket;

import java.util.List;

public class Main {
    public static void main(String[] args) {
        // S3 credentials and endpoint
        String accessKey = "YOUR_ACCESS_KEY"; // Replace with your access key
        String secretKey = "YOUR_SECRET_KEY"; // Replace with your secret key
        String endpoint = "HOST_NAME" //Use the Hostname from the Details page.
        String region = "US";

        // Create S3 client
        AmazonS3 s3 = AmazonS3ClientBuilder.standard()
            .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(endpoint, region))
            .withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials(accessKey, secretKey)))
            .withPathStyleAccessEnabled(true)
            .build();

        try {
            List<Bucket> buckets = s3.listBuckets();
            System.out.println("Buckets:");
            for (Bucket bucket : buckets) {
                System.out.println("  - " + bucket.getName());
            }
        } catch (Exception e) {
            System.err.println("Error: " + e.getMessage());
        }
    }
}
```

## Explanation

### Steps in the Code

1. **Credentials**: The program uses `BasicAWSCredentials` to provide the access key and secret key. Make sure to replace `YOUR_ACCESS_KEY` and `YOUR_SECRET_KEY` with your actual credentials.
2. **Client Configuration**: The `AmazonS3ClientBuilder` is configured with the endpoint and region of the S3-compatible service. The `.withPathStyleAccessEnabled(true)` ensures path-style access to the buckets.
3. **List Buckets**: The `listBuckets` method is called on the `AmazonS3` client to retrieve all the available buckets. These buckets are then printed to the console.
4. **Error Handling**: If an error occurs during the process, it is caught in the `catch` block, and the error message is printed.

## Run the Code

To run the program, you can compile and execute it as a standard Java application. Make sure to have the AWS SDK for Java dependency correctly added to your project.

***

**Note**: Ensure that you replace the placeholders for access key and secret key with your own credentials. These credentials should be securely stored and not hardcoded in production applications.


# API Keys

Create, reveal, disable, and delete Nebula Block API keys, including team keys, and keep them secure.

An API key authenticates your requests to both the [Inference API](/api-reference/inference-api) and the [Platform API](/api-reference/platform-api). Keys are long-lived — unlike access tokens, they do not expire — which makes them the right credential for applications, servers, and CI.

## Managing keys in the console

Go to [**API Keys**](https://console.nebulablock.com/apiKeys) in the console. From there you can:

* **Create a key.** Give it a name — names must be unique within your account — and an optional description. The key value can be revealed and copied from the key list at any time, so losing it is not a reason to rotate; suspecting it leaked is.
* **Disable a key.** Disabling stops the key authenticating immediately, and it can be re-enabled later. Use this rather than deleting when you only need to cut access temporarily.
* **Delete a key.** Permanent, and anything still using it starts failing with `401`.

An account can hold up to **20** API keys at once. If you need more, contact support.

> **Note:** Keys cannot be regenerated in place. To rotate one, create a replacement, move your applications over, and then delete the old key.

## Using a key

Send it as a Bearer token:

```
Authorization: Bearer sk-...
```

```bash
curl https://inference.nebulablock.com/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $NEBULA_API_KEY" \
  -d '{"model": "deepseek-ai/DeepSeek-V3.2", "messages": [{"role": "user", "content": "Hello"}]}'
```

All Nebula Block API keys are prefixed with `sk-`.

## Team keys

A key can belong to a [team](/account/teams) instead of to you personally. Team keys draw on the team's resources and are visible to the team's members, which is what you want for shared services rather than personal experiments. Create one by selecting the team when you create the key, or by passing `team_id` to [Create API Key](/api-reference/platform-api/list-api-keys/create-api-key).

## Keeping keys safe

* Keep keys out of source control and out of client-side code. Load them from environment variables or a secrets manager.
* Give each application its own key, so you can revoke one without disrupting the others.
* If a key may have leaked, disable it immediately, then create a replacement and delete the old one.
* Usage and spend are attributed per key, so separate keys also make it easier to see where cost comes from.

## Managing keys through the API

|                                                                            |                     |
| -------------------------------------------------------------------------- | ------------------- |
| [List API Keys](/api-reference/platform-api/list-api-keys)                 | `GET /keys`         |
| [Create API Key](/api-reference/platform-api/list-api-keys/create-api-key) | `POST /keys`        |
| [Update API Key](/api-reference/platform-api/list-api-keys/update-api-key) | `PUT /keys/{id}`    |
| [Delete API Key](/api-reference/platform-api/list-api-keys/delete-api-key) | `DELETE /keys/{id}` |

## See also

* [Authentication](/api-reference/authentication)
* [Teams](/account/teams)
* [Glossary](/resources/glossary)


# Tiers and Rate Limits

Nebula Block's four tiers and what each unlocks: RPM, TPM, RPD, per-model daily caps, credit ceilings, and CPU/GPU access.

Every Nebula Block account sits in one of four tiers. Your tier determines how fast you can call the serverless inference endpoints, whether you can rent CPU and GPU instances, and how much credit you can hold.

Tiers are reached by **depositing** or **spending** credit — there is nothing to apply for, and upgrades are applied automatically once you meet the requirement.

> **Tier vs. spending limit.** Your tier decides *whether* you can rent GPU instances. How *much* GPU you can run at the same time is a separate, per-account [hourly spending limit](/getting-started/get-started/spending-limits) that starts at $4/hour and grows with your payment history or on request.

## Tier comparison

|                               | **Tier 1**         | **Tier 2** | **Tier 3**  | **Tier 4** |
| ----------------------------- | ------------------ | ---------- | ----------- | ---------- |
| **Requirement**               | Free — sign up     | $5 deposit | $10 deposit | $100 spend |
| **Serverless inference**      | ✔ (limited models) | ✔          | ✔           | ✔          |
| **CPU instances**             | ✖                  | ✔          | ✔           | ✔          |
| **GPU instances**             | ✖                  | ✖          | ✔           | ✔          |
| **Requests per minute (RPM)** | 60                 | 300        | 600         | 1,500      |
| **Tokens per minute (TPM)**   | 200,000            | 1,000,000  | 2,000,000   | 4,000,000  |
| **Requests per day (RPD)**    | 200                | 1,000      | 2,000       | 500,000    |
| **Maximum credit balance**    | $20                | $50        | $200        | $2,000     |

> **Note:** RPD counters reset at 00:00 UTC.

## Per-model daily limits

The account-wide RPD in the table above is not the only limit. **Each model also carries its own daily request cap per tier**, which is why a Tier 2 account can make 1,000 requests per day overall but far more than that against a single high-volume model.

Two consequences worth knowing before you build:

* **Paid models are not available on Tier 1.** Their per-model cap on the free tier is 0, so calling one returns HTTP `429` with `"Daily request limit reached for this model … Please upgrade your tier or try again tomorrow."` A $5 deposit (Tier 2) is what unlocks the paid catalog.
* **Limits are per model, not per family.** Two models from the same provider can have different caps.

The authoritative, always-current numbers for your account are in the console under [**Limits**](https://console.nebulablock.com/limits) — it shows your current tier, the per-model daily limit for every model, and what that limit becomes at the next tier.

## How to upgrade

| To reach   | Do this                |
| ---------- | ---------------------- |
| **Tier 2** | Deposit a total of $5  |
| **Tier 3** | Deposit a total of $10 |
| **Tier 4** | Spend a total of $100  |

Deposits are cumulative across your account's lifetime, not per transaction. Add credit from [**Billing**](https://console.nebulablock.com/billing) in the console — see [Billing Information](/getting-started/get-started/billing) for payment methods, auto-pay, and invoices.

Tier upgrades are processed automatically; your new limits take effect without any action on your part.

## Rate limit errors

| Status                                             | Meaning                                                                                         | What to do                                                        |
| -------------------------------------------------- | ----------------------------------------------------------------------------------------------- | ----------------------------------------------------------------- |
| `429` — daily request limit reached for this model | You hit the per-model RPD cap for your tier, or the model is a paid model and you are on Tier 1 | Upgrade your tier, switch models, or wait for the 00:00 UTC reset |
| `429` — daily request limit reached                | You hit your account-wide RPD                                                                   | Upgrade your tier or wait for the 00:00 UTC reset                 |
| `429` — rate limit exceeded (RPM/TPM)              | You exceeded requests or tokens per minute                                                      | Retry with exponential backoff                                    |

## See also

* [Limits in the console](https://console.nebulablock.com/limits)
* [Billing Information](/getting-started/get-started/billing)
* [Model Catalog](/products/serverless-inference/model-catalog)
* [Referral Program](/account/referral)


# Teams

Create a Nebula Block team, invite members, assign roles and permissions, and share API keys and resources.

## Teams

Teams on Nebula Block allow you to collaborate with other users, share resources, and manage access to your inferences. With Teams, you can invite colleagues, assign roles, and work together seamlessly on your projects.

### Getting Started with Teams

#### Create a Team

To create your own team on Nebula Block:

1. Sign up for an account at[ nebulablock.com](https://nebulablock.com/)
2. Login to your account
3. In the left panel, click Team
4. Click the Create Team button

<figure><img src="https://540120125-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FXZhubbpeVAa2uzXxQcny%2Fuploads%2Fgit-blob-740dedc5679903b6bd025eb8d186159c87ff1f42%2F01.png?alt=media" alt=""><figcaption></figcaption></figure>

5. Fill in your team name and team description

<figure><img src="https://540120125-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FXZhubbpeVAa2uzXxQcny%2Fuploads%2Fgit-blob-8ac942bea2118f625305911e72edcde6efb7c96f%2F02.png?alt=media" alt=""><figcaption></figcaption></figure>

6. Click Create to establish your team

#### Join an Existing Team

If you've been invited to join a team:

1. Accept the invitation link sent by a team owner
2. Select Accept Invitation on the invitation page

Note: If you haven't registered yet, please[ sign up here](https://console.nebulablock.com/register) first. Once registered, return to the invitation link to complete the process.

<figure><img src="https://540120125-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FXZhubbpeVAa2uzXxQcny%2Fuploads%2Fgit-blob-9c98d94b617f704a8c9a99c933da58e77cd5a73c%2F03.png?alt=media" alt=""><figcaption></figcaption></figure>

### Managing Team Members

#### Invite a User

To invite users to your team:

1. Navigate to your Team page
2. In the Members Management section, select the Invite Member button

<figure><img src="https://540120125-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FXZhubbpeVAa2uzXxQcny%2Fuploads%2Fgit-blob-7d9bab7a3a90ba0f02dc57f4bfa89947eb9af7a8%2F04.png?alt=media" alt=""><figcaption></figcaption></figure>

3. Select the role you want to assign to the new user
4. After creating the invite, copy the invite link

<figure><img src="https://540120125-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FXZhubbpeVAa2uzXxQcny%2Fuploads%2Fgit-blob-1d0ab016115921a0ce99b9602da9bdde7ff10854%2F05.png?alt=media" alt=""><figcaption></figcaption></figure>

5. Send the invite link to the user you want to invite
6. The invited user can click the link to join your team

#### Managing Invitations

You can track and manage all pending invitations in the Pending Invites section of your Team page. This allows you to:

* View all outstanding invitations
* Cancel pending invitations

<figure><img src="https://540120125-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FXZhubbpeVAa2uzXxQcny%2Fuploads%2Fgit-blob-371a78de0169f5ba782c5812f4217f5ca0c6921b%2F06.png?alt=media" alt=""><figcaption></figcaption></figure>

### Role Types and Permissions

Nebula Block Teams offer different role types with specific permissions to ensure proper access control:

#### Member Role

Limited access, primarily for account usage and existing inferences connections.

Permissions:

* Use the account and its resources
* Connect to and use Inferences
* View personal usage analytics and see how models are being used

<figure><img src="https://540120125-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FXZhubbpeVAa2uzXxQcny%2Fuploads%2Fgit-blob-d86c890e83ec1b3f5ecaf060c37004da3a3d8612%2F07.png?alt=media" alt=""><figcaption></figcaption></figure>

#### Admin Role

Specialized role focused on managing resources and administrative aspects.

Permissions:

* All Member role permissions (use account, connect to Infereneces)
* Memeber management
* View detailed usage analytics and statistics for team's inference requests

<figure><img src="https://540120125-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FXZhubbpeVAa2uzXxQcny%2Fuploads%2Fgit-blob-33e222d1a297c78e9ebbe18f9d7d1b0b5d631eb4%2F08.png?alt=media" alt=""><figcaption></figcaption></figure>

#### Owner Role

Full control over the account, ideal for primary administrators.

Permissions:

* All Admin and Member permissions
* Full control over account resources and members
* Create and delete Teams
* Transfer ownership of the Team

<figure><img src="https://540120125-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FXZhubbpeVAa2uzXxQcny%2Fuploads%2Fgit-blob-429a6fea25c4f1dda554aa5b77ebeae49bda28cb%2F09.png?alt=media" alt=""><figcaption></figcaption></figure>

### Dashboard

The Teams dashboard provides a centralized view of your team's activity, member management, and resource usage. Access all team features from this unified interface.

### Usage Analytics

Teams provide comprehensive usage analytics to help you monitor and optimize your resource consumption:

* Model Usage Statistics: See how your team has been using models on Nebula Block
* Detailed Usage Records: Access granular data about your team's inference requests
* Resource Monitoring: Track Inferences usage, billing, and performance metrics

<figure><img src="https://540120125-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FXZhubbpeVAa2uzXxQcny%2Fuploads%2Fgit-blob-13ec3acf8e04b8c10726eea49f05b3af324b0154%2F10.png?alt=media" alt=""><figcaption></figcaption></figure>

### Team API Keys

#### API Key Security

API keys provide full access to your team's resources and should be handled with care:

* Keep API keys secure and never share them publicly
* Never commit API keys to version control or publicly accessible repositories
* Rotate keys regularly for enhanced security
* Use environment variables to store API keys in your applications

<figure><img src="https://540120125-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FXZhubbpeVAa2uzXxQcny%2Fuploads%2Fgit-blob-a95dae0292e6cd6d06263fca4c28420ac6595071%2F11.png?alt=media" alt=""><figcaption></figcaption></figure>

\\


# Referral Program

Earn commission on the spend of users you refer to Nebula Block, and apply a referral code to your account.

Nebula Block's referral program rewards users for inviting others to join our platform. Each user receives a unique referral code upon signing up, which can be shared with others to earn bonuses and commissions.

## Referral Commission Tiers

Referrers (user making the referral) earn commissions based on the total spending of their referees (user being referred by the referrer). The commission structure is as follows:

| Tier | Referees' Total Spend | Serverless Endpoint Commission | Compute Commission |
| ---- | --------------------- | ------------------------------ | ------------------ |
| 1    | $0 - $1,000           | 3%                             | 1%                 |
| 2    | $1,000 - $2,500       | 5%                             | 1%                 |
| 3    | $2,500 - $5,000       | 10%                            | 1%                 |
| 4    | $5,000 and above      | 15%                            | 1%                 |

> **Note:** Your referral tier is determined by the **cumulative spend of everyone you have referred**, not by your own account tier. Your current tier, referral count, and earnings are shown under [Referral](https://console.nebulablock.com/referral) in the console.

## Earnings and Payout

* Your **total successful referrals** and **earnings** are shown under [Referral](https://console.nebulablock.com/referral) in the console.
* Payouts are made on the **first day of each month**.
* Earnings are **credited directly** to the user's account as platform credits.

## How to Apply a Referral Code

1. Sign in to the [console](https://console.nebulablock.com).
2. Open [**Referral**](https://console.nebulablock.com/referral).
3. Enter the referral code and apply it.

Your own referral code lives on the same page, along with your referral count and current earnings.

## See also

* [Billing](/getting-started/get-started/billing)
* [Tiers and Rate Limits](/account/tiers-and-limits)


# Overview

Reference for Nebula Block's two APIs — the OpenAI-compatible Inference API and the Platform API.

Nebula Block exposes two APIs. They share one credential, so a single API key works against both.

| API                                               | Base URL                               | Use it for                                                                 |
| ------------------------------------------------- | -------------------------------------- | -------------------------------------------------------------------------- |
| [**Inference API**](/api-reference/inference-api) | `https://inference.nebulablock.com/v1` | Running models: chat, vision, images, video, embeddings, reranking         |
| [**Platform API**](/api-reference/platform-api)   | `https://api.nebulablock.com/api/v1`   | Managing resources: instances, SSH keys, API keys, object storage, billing |

The Inference API implements the OpenAI API surface, so existing OpenAI SDKs work against it by changing the base URL. The Platform API is a conventional REST API that wraps every response in a `data` / `message` / `status` envelope.

## Authenticating

Both APIs use Bearer authentication:

```
Authorization: Bearer sk-...
```

Create a key in the console under [API Keys](https://console.nebulablock.com/apiKeys). See [Authentication](/api-reference/authentication) for access tokens, login, and the rules around key rotation.

## Rate limits

Inference calls are subject to per-minute and per-day limits that depend on your tier, plus a per-model daily cap. Exceeding either returns `429`. See [Tiers and Rate Limits](/account/tiers-and-limits).

## Before you provision compute

Renting GPU instances requires an SSH key on your account, so that you can reach the instance once it is running. Add one in the console under [SSH Keys](https://console.nebulablock.com/sshKey), or with [Create SSH Key](/api-reference/platform-api/list-ssh-keys/create-ssh-key).

## See also

* [Quickstart](/getting-started/get-started/quickstart)
* [Model Catalog](/products/serverless-inference/model-catalog)
* [Glossary](/resources/glossary)


# Authentication

Authenticate to Nebula Block with an API key or a login access token, and manage key rotation.

Every Nebula Block endpoint requires authentication, so the platform knows whose resources to read or change. There are two credential types:

* [**API keys**](#api-keys) — long-lived, for applications and servers
* [**Access tokens**](#access-tokens) — short-lived JWTs, for interactive sessions

Both use Bearer authentication:

```
Authorization: Bearer <key or token>
```

## API keys

API keys are the right choice for anything running unattended: they do not expire, and you can disable or delete one without touching the rest of your account.

```
Authorization: Bearer sk-...
```

API keys are prefixed with `sk-`, which is how they are told apart from access tokens. The same key authenticates both the [Inference API](/api-reference/inference-api) and the [Platform API](/api-reference/platform-api).

Create and manage keys in the console under [API Keys](https://console.nebulablock.com/apiKeys), or through the API — see [Create API Key](/api-reference/platform-api/list-api-keys/create-api-key). A few constraints worth knowing:

* Key names must be unique within your account.
* An account can hold up to **20** API keys. Contact support if you need the cap raised.
* Keys cannot be regenerated in place. To rotate one, create a replacement and delete the old key.
* A key can be disabled and re-enabled with [Update API Key](/api-reference/platform-api/list-api-keys/update-api-key), which is safer than deleting if you only need to cut access temporarily.

> **Important:** Key values are readable after creation — both [List API Keys](/api-reference/platform-api/list-api-keys) and the console return them in full. Treat a key like a password: keep it out of source control, and rotate it if you suspect it has leaked.

## Access tokens

Access tokens are JWTs issued by the [login endpoint](#login). They suit interactive tools and the console, where a human has just entered credentials.

```
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
```

> **Note:** Access tokens expire **24 hours** after they are issued. Once one expires, requests fail with `401` and you need to log in again for a new token. For anything long-running, use an API key instead.

## Login

### HTTP Request

`POST` `{API_URL}/login`

where `API_URL = https://api.nebulablock.com/api/v1`.

The endpoint takes OAuth2 password-form input, so the body must be form-encoded, not JSON.

### Body Parameters

| Parameter  | Requirement | Type     | Description           |
| ---------- | ----------- | -------- | --------------------- |
| `username` | Required    | `string` | Your account email    |
| `password` | Required    | `string` | Your account password |

### Response Attributes

#### data `dict`

Your account summary plus the access token in `jwtToken`.

#### status `string`

`success` or `failed`.

#### message `string`

A description of the result.

### Example

#### Request

```bash
curl -X POST '{API_URL}/login' \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'username=testemail@gmail.com' \
--data-urlencode 'password=your-password'
```

#### Response

```json
{
    "data": {
        "id": 18,
        "name": "Test User",
        "email": "testemail@gmail.com",
        "is_staff": false,
        "is_active": true,
        "jwtToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
    },
    "message": "Login successful",
    "status": "success"
}
```

## Logout

`POST` `{API_URL}/logout`

Invalidates the access token supplied in the `Authorization` header. API keys are unaffected — delete or disable them instead.

## See also

* [API Keys](/account/api-keys)
* [Platform API](/api-reference/platform-api)
* [Inference API](/api-reference/inference-api)


# Inference API

The OpenAI-compatible Inference API: chat completions, vision, images, video, embeddings, and reranking.

The Inference API runs models. It implements the OpenAI API surface, so existing OpenAI SDKs and tools work against it once you change the base URL.

* **Base URL:** `https://inference.nebulablock.com/v1`
* **Authentication:** `Authorization: Bearer <your API key>` — see [Authentication](/api-reference/authentication)

> **Note:** These endpoints are also reachable at `https://api.nebulablock.com/v1`. Prefer the `inference.nebulablock.com` host.

## Endpoints

| Endpoint                                                                                | What it does                    |
| --------------------------------------------------------------------------------------- | ------------------------------- |
| [`GET /v1/models`](/api-reference/inference-api/list-models)                            | List every model you can call   |
| [`POST /v1/chat/completions`](/api-reference/inference-api/chat-completions)            | Chat and text generation        |
| [`POST /v1/chat/completions`](/api-reference/inference-api/vision) (with image content) | Image understanding             |
| [`POST /v1/images/generations`](/api-reference/inference-api/images)                    | Image generation                |
| [`POST /v1/videos/generations`](/api-reference/inference-api/videos)                    | Video generation (asynchronous) |
| [`POST /v1/embeddings`](/api-reference/inference-api/embeddings)                        | Text embeddings                 |
| [`POST /v1/rerank`](/api-reference/inference-api/rerank)                                | Document reranking              |

## Using an OpenAI SDK

```python
import os

from openai import OpenAI

client = OpenAI(
    base_url="https://inference.nebulablock.com/v1",
    api_key=os.environ["NEBULA_API_KEY"],
)
```

## See also

* [Serverless Inference](/products/serverless-inference)
* [Model Catalog](/products/serverless-inference/model-catalog)
* [Platform API](/api-reference/platform-api)


# List Models

List the models available on Nebula Block, either OpenAI-style or with full catalog metadata and per-tier limits.

Two endpoints return the model catalog: an OpenAI-compatible one that lists model IDs, and a richer one that adds context lengths, pricing, and per-tier limits.

## OpenAI-compatible list

Use this when you want the same response shape an OpenAI client expects — for example to populate a model picker through an SDK.

### HTTP Request

`GET` `https://inference.nebulablock.com/v1/models`

### Response Attributes

#### object `string`

Always `list`.

#### data `list`

The available models. Each entry contains:

* **id** `string`: The model ID. This is the value you pass as `model` in an inference request.
* **object** `string`: Always `model`.
* **created** `integer`: Unix timestamp of when the model was added.
* **owned\_by** `string`: The model's provider.

### Example

#### Request

```bash
curl -X GET 'https://inference.nebulablock.com/v1/models' \
-H 'Authorization: Bearer {TOKEN/KEY}'
```

#### Response

```json
{
    "object": "list",
    "data": [
        {
            "id": "gemini/gemini-3.7-flash",
            "object": "model",
            "created": 1786647688,
            "owned_by": "google"
        },
        {
            "id": "deepseek-ai/DeepSeek-V3.2",
            "object": "model",
            "created": 1785780016,
            "owned_by": "deepseek-ai"
        }
    ]
}
```

## Full catalog

Use this when you need more than the ID — context length, pricing, or the per-tier daily limits that apply to a model.

### HTTP Request

`GET` `https://api.nebulablock.com/api/v1/serverless/models`

### Response Attributes

#### data `dict`

Contains `models`, a list of model objects. Each has:

* **model\_name** `string`: The unique model ID. Pass this as `model` in inference calls.
* **model\_alias** `string`: The human-readable display name.
* **model\_type** `string`: `Text`, `multimodal`, `Vision`, `Image`, `Video`, `Embedding`, or `Rerank`.
* **context\_length** `integer`: Context window in tokens, or `null` for media models.
* **max\_completion\_tokens** `integer`: Maximum tokens the model will generate, where applicable.
* **description** `string`: A short description of the model.
* **input\_price** / **output\_price** `float`: List price. The unit depends on the model type — per 1M tokens for text and multimodal models, per image or per second for media models. Promotional rates are applied on top and are not reflected here; see the [pricing page](https://www.nebulablock.com/pricing/serverless-ai).
* **cache\_read\_input\_price** / **cache\_creation\_input\_price** `float`: Prompt-caching rates, where the model supports caching.
* **hosting\_in** `string`: Where the model is hosted. `CA` marks Canadian-hosted models.
* **parameter\_size** `string`: Parameter count, for open-weight models.
* **huggingface\_url** `string`: The model's Hugging Face page, where applicable.
* **restrictions** `dict`: The daily request cap per tier — `RPD_ENGINEER_TIER_1` through `RPD_EXPERT_TIER_1`. A value of `0` means the model cannot be called on that tier. See [Tiers and Rate Limits](/account/tiers-and-limits).
* **tags** `dict`: `modality`, `use_case`, `highlight`, and `model_family` labels.

#### status `string`

`success` or `failed`.

#### message `string`

A description of the result.

### Example

#### Request

```bash
curl -X GET 'https://api.nebulablock.com/api/v1/serverless/models' \
-H 'Content-Type: application/json'
```

#### Response

```json
{
    "data": {
        "models": [
            {
                "model_name": "gemini/gemini-3.7-flash",
                "model_alias": "Gemini-3.7-Flash",
                "model_type": "multimodal",
                "context_length": 1048576,
                "max_completion_tokens": 65536,
                "description": "Google's newest Flash model — stronger multimodal reasoning, coding and agentic performance at Flash speed",
                "input_price": 1.5,
                "output_price": 7.5,
                "cache_read_input_price": 0.075,
                "cache_creation_input_price": null,
                "hosting_in": "-",
                "parameter_size": "-",
                "huggingface_url": "",
                "restrictions": {
                    "restriction_type": "model_name",
                    "restriction_name": "gemini/gemini-3.7-flash",
                    "RPD_ENGINEER_TIER_1": 0,
                    "RPD_ENGINEER_TIER_2": 5000,
                    "RPD_ENGINEER_TIER_3": 10000,
                    "RPD_EXPERT_TIER_1": 50000
                },
                "tags": {
                    "modality": ["multimodal", "text_generation"],
                    "use_case": [],
                    "highlight": ["recently_added", "featured"],
                    "model_family": ["Gemini"]
                }
            }
        ]
    },
    "message": "Get models list successfully.",
    "status": "success"
}
```

## See also

* [Model Catalog](/products/serverless-inference/model-catalog)
* [Tiers and Rate Limits](/account/tiers-and-limits)
* [Chat Completions](/api-reference/inference-api/chat-completions)


# Chat Completions

Generate chat completions with Nebula Block's text and multimodal models through the OpenAI-compatible API.

Return the generated text based on the given inputs.

## HTTP Request

`POST` `{API_URL}/chat/completions`

where the `API_URL = https://inference.nebulablock.com/v1`. The body has the following parameters:

* **messages** `array`: An array of message objects. Each object should have:
  * **role** `string`: The role of the message sender (e.g., "user").
  * **content** `string`: The content of the message.
* **model** `string`: The model to use for generating the response.
* **max\_tokens** `integer or null`: The maximum number of tokens to generate. If null, the model's default will be used.
* **temperature** `float`: Sampling temperature. Higher values make the output more random, while lower values make it more focused and deterministic.
* **top\_p** `float`: Nucleus sampling probability. The model will consider the results of the tokens with top\_p probability mass. In other words, a higher value will result in more diverse outputs, while a lower value will result in more repetitive outputs.
* **stream** `boolean`: Whether to stream the response in chunks or not.

## Response Attributes

#### id `string`

A unique identifier for the completion request.

#### created `integer`

A Unix timestamp representing when the response was generated.

#### model `string`

The specific AI model used to generate the response.

#### object `string`

The type of response object (e.g., `"chat.completion.chunk"` for a streamed chunk or `chat.completion` for a non-chunked completion).

#### system\_fingerprint `string`

A unique identifier for the system that generated the response, if available.

#### choices `array`

An array containing completion objects. Each object has the following fields:

* **finish\_reason** `string`: The reason the completion finished.
* **index** `integer`: An index demarking this completion object.
* **message** `dict`: Contains data on the generated output.
  * **content** `string`: The generated text for this completion object.
  * **role** `string`: Specifies the role of the AI (e.g., "assistant").
  * **tool\_calls** `array`: Contains information about the tools used in generating the completion, if available.
  * **function\_calls** `array`: Contains information about the functions used in generating the completion, if available.

#### usage `dict`

A dictionary containing information about the inference request, in key-value pairs:

* **completion\_tokens** `integer`: The number of tokens generated in the completion for a completion action.
* **prompt\_tokens** `integer`: The number of tokens in the prompt.
* **total\_tokens** `integer`: The total number of tokens (prompt and completion combined).
* **completion\_tokens\_details** `null`: Additional details about the completion tokens, if available.
* **prompt\_tokens\_details** `null`: Additional details about the prompt tokens, if available.

#### service\_tier `string`

The service tier used for the completion request.

#### prompt\_logprobs `array`

An array containing the log probabilities of the tokens in the prompt, if available.

## Example

#### Request

```bash
curl -X POST '{API_URL}/chat/completions' \
-H 'Authorization: Bearer {TOKEN/KEY}' \
-H 'Content-Type: application/json' \
-d '{
    "messages": [
        {
            "role": "user",
            "content": "insert your prompt here"
        }
    ],
    "model": "deepseek-ai/DeepSeek-V3.2",
    "max_tokens": null,
    "temperature": 1,
    "top_p": 0.9,
    "stream": true
}'
```

#### Response

Here's an example of a successful response in the non-streaming option. This response contains a `chat.completion` object and represents the entire generated text:

```json
{
    "id": "chatcmpl-ec0014bc38e2cad1e45d47f7f01f6569",
    "created": 1740432179,
    "model": "deepseek-ai/DeepSeek-V3.2",
    "object": "chat.completion",
    "system_fingerprint": null,
    "choices": [
        {
            "finish_reason": "stop",
            "index": 0,
            "message": {
                "content": "Yes! Montreal is the home of cutting edge ... research.",
                "role": "assistant",
                "tool_calls": null,
                "function_call": null
            }
        }
    ],
    "usage": {
        "completion_tokens": 695,
        "prompt_tokens": 42,
        "total_tokens": 737,
        "completion_tokens_details": null,
        "prompt_tokens_details": null
    },
    "service_tier": null,
    "prompt_logprobs": null
}
```

Alternatively, if you set `stream` to True you'll get a stream of `chat.completion.chunk` objects. The entire collection of chunks represents the complete generated response.

```json
{
    "id": "chatcmpl-3061dfd6d9170825ba0fb54086c4dad3",
    "created": 1740081592,
    "model": "deepseek-ai/DeepSeek-V3.2",
    "object": "chat.completion.chunk",
    "choices": [
        {
            "index": 0,
            "delta": {
                "content": "It",
                "role": "assistant"
            }
        }
    ]
}
{
    "id": "chatcmpl-3061dfd6d9170825ba0fb54086c4dad3",
    "created": 1740081592,
    "model": "deepseek-ai/DeepSeek-V3.2",
    "object": "chat.completion.chunk",
    "choices": [
        {
            "index": 0,
            "delta": {
                "content": " looks"
            }
        }
    ]
}
...
[DONE]
```

For more examples, see the [Inference\_Models](/products/serverless-inference/text-generation) section.


# Vision

Send images alongside text to Nebula Block's vision and multimodal models and get a text response.

Return the generated text based on the given textual and image inputs.

## HTTP Request

`POST` `{API_URL}/chat/completions`

where the `API_URL = https://inference.nebulablock.com/v1`. The body has the following parameters:

* **messages** `array`: An array of message objects. Each object should have:
  * **role** `string`: The role of the message sender (e.g., "user").
  * **content** `list`: A list containing the different inputs (recall an input can be either text or image). Each input is represented as a dict with the following key-value pairs:
    * **type** `string`: The type of input (e.g., "text" or "image\_url").
    * **image\_url** `dict`: If type is "image\_url", this contains a dict representing the URL of the image with the following key-value pair:
      * **url** `string`: The URL of the image.
    * **text** `string`: If type is "text", the text input.

Note that only one of `url` or `text` can be provided in the input dict, and depends on the `type`.

* **model** `string`: The model to use for generating the response.
* **max\_tokens** `integer or null`: The maximum number of tokens to generate. If null, the model's default will be used.
* **temperature** `float`: Sampling temperature. Higher values make the output more random, while lower values make it more focused and deterministic.
* **top\_p** `float`: Nucleus sampling probability. The model will consider the results of the tokens with top\_p probability mass. In other words, a higher value will result in more diverse outputs, while a lower value will result in more repetitive outputs.
* **stream** `boolean`: Whether to stream the response in chunks or not.

## Response Attributes

#### id `string`

A unique identifier for the completion request.

#### created `integer`

A Unix timestamp representing when the response was generated.

#### model `string`

The specific AI model used to generate the response.

#### object `string`

The type of response object (e.g., `"chat.completion.chunk"` for a streamed chunk or `chat.completion` for a non-chunked completion).

#### system\_fingerprint `string`

A unique identifier for the system that generated the response, if available.

#### choices `array`

An array containing completion objects. Each object has the following fields:

* **finish\_reason** `string`: The reason the completion finished.
* **index** `integer`: An index demarking this completion object.
* **message** `dict`: Contains data on the generated output.
  * **content** `string`: The generated text for this completion object.
  * **role** `string`: Specifies the role of the AI (e.g., "assistant").
  * **tool\_calls** `array`: Contains information about the tools used in generating the completion, if available.
  * **function\_calls** `array`: Contains information about the functions used in generating the completion, if available.

#### usage `dict`

A dictionary containing information about the inference request, in key-value pairs:

* **completion\_tokens** `integer`: The number of tokens generated in the completion for a completion action.
* **prompt\_tokens** `integer`: The number of tokens in the prompt.
* **total\_tokens** `integer`: The total number of tokens (prompt and completion combined).
* **completion\_tokens\_details** `null`: Additional details about the completion tokens, if available.
* **prompt\_tokens\_details** `null`: Additional details about the prompt tokens, if available.

#### service\_tier `string`

The service tier used for the completion request.

#### prompt\_logprobs `array`

An array containing the log probabilities of the tokens in the prompt, if available.

## Example

#### Request

```bash
curl -X POST "https://inference.nebulablock.com/v1/chat/completions" \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $NEBULA_API_KEY" \
    --data-raw '{
        "messages": [
			{"role":"user","content":[
			{"type":"image_url","image_url":
			{"url":"https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen-VL/assets/demo.jpeg"}},
			{"type":"text","text":"What is this image?"}
		]}],
        "model": "Qwen/Qwen2.5-VL-7B-Instruct",
        "max_tokens": null, 
        "temperature": 1,
        "top_p": 0.9,
        "stream": false
    }'
```

#### Response

A successful generation response (non-streaming) will contain a `chat.completion` object, and should look like this:

```json
    {
    "id": "chatcmpl-7ba48f119a564f4ea02b6a41386a3e40",
    "created": 1740689977,
    "model": "Qwen/Qwen2.5-VL-7B-Instruct",
    "object": "chat.completion",
    "system_fingerprint": null,
    "choices": [
        {
            "finish_reason": "stop",
            "index": 0,
            "message": {
                "content": "This image shows ....",
                "role": "assistant",
                "tool_calls": null,
                "function_call": null
            }
        }
    ],
    "usage": {
        "completion_tokens": 91,
        "prompt_tokens": 3604,
        "total_tokens": 3695,
        "completion_tokens_details": null,
        "prompt_tokens_details": null
    },
    "service_tier": null,
    "prompt_logprobs": null
}
```

As is the case with text generation, if you set `stream` to True you can get the entire generated completion in 1 `chat.completion` object:

```json
{
    "id": "chatcmpl-3812731562554b23a32dd80fbb7d0d09",
    "created": 1740692435,
    "model": "Qwen/Qwen2.5-VL-7B-Instruct",
    "object": "chat.completion.chunk",
    "choices": [
        {
            "index": 0,
            "delta": {
                "content": " setting"
            }
        }
    ]
}
{ 
  ...
}
...
```

For more examples, see the [Inference Models](/products/serverless-inference/vision) section.


# Images

Generate and edit images through Nebula Block's OpenAI-compatible images endpoints.

Generate an image from a prompt, or edit an existing image. For a walkthrough, see [Image Generation](/products/serverless-inference/image-generation).

## Create an image

### HTTP Request

`POST` `{API_URL}/images/generations`

where `API_URL = https://inference.nebulablock.com/v1`.

### Body Parameters

#### model `string` *required*

The image model to use, for example `gemini/gemini-3.1-flash-image-preview`.

#### prompt `string` *required*

A text description of the image to generate.

#### n `integer`

Number of images to generate. Defaults to `1`.

#### size `string`

Output size as `WxH`. Mapped to the nearest aspect ratio the model supports — `1:1`, `16:9`, `9:16`, `4:3`, `3:4`, `3:2`, `2:3`, `21:9`, `4:5`, or `5:4`.

#### response\_format `string`

`b64_json` or `url`. Defaults to `b64_json`.

#### user `string`

An optional identifier for the end user making the request.

#### provider\_options `dict`

Model-specific options passed through to the provider. Commonly supported keys:

* **aspect\_ratio** `string`: Set the aspect ratio directly instead of via `size`.
* **image\_size** `string`: Output resolution, where the model supports more than one.
* **image\_urls** `list`: Reference images to condition the generation on.
* **person\_generation** `string`: The model's policy for generating people.
* **output\_mime\_type** `string`: Output format, such as `image/png`.
* **compression\_quality** `integer`: Compression quality for lossy formats.
* **thinking\_level** `string`: How much the model reasons before generating.

### Response Attributes

#### created `integer`

Unix timestamp of when the images were generated.

#### data `list`

The generated images. Each entry contains **b64\_json** `string`, the base64-encoded image.

### Example

#### Request

```bash
curl -X POST "https://inference.nebulablock.com/v1/images/generations" \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $NEBULA_API_KEY" \
    --data-raw '{
        "model": "gemini/gemini-3.1-flash-image-preview",
        "prompt": "A snowy street in Old Montreal at dusk, warm window light",
        "size": "1536x1024"
    }'
```

#### Response

```json
{
    "created": 1756944000,
    "data": [
        { "b64_json": "iVBORw0KGgoAAAANSUhEUg..." }
    ]
}
```

## Edit an image

### HTTP Request

`POST` `{API_URL}/images/edits`

This endpoint takes `multipart/form-data`, not JSON.

### Form Parameters

| Parameter | Requirement | Type     | Description                                                          |
| --------- | ----------- | -------- | -------------------------------------------------------------------- |
| `image`   | Required    | `file`   | The image to edit. PNG, JPEG, WebP, or GIF                           |
| `prompt`  | Required    | `string` | A description of the desired edit                                    |
| `model`   | Required    | `string` | An image-editing model, such as `gemini/gemini-2.5-flash-image-edit` |
| `size`    | Optional    | `string` | Output size as `WxH`. Defaults to `1024x1024`                        |

### Example

#### Request

```bash
curl -X POST "https://inference.nebulablock.com/v1/images/edits" \
    -H "Authorization: Bearer $NEBULA_API_KEY" \
    -F 'model=gemini/gemini-2.5-flash-image-edit' \
    -F 'prompt=Replace the sky with an aurora' \
    -F 'image=@./input.png'
```

#### Response

The same shape as image creation — a `created` timestamp and a `data` array of base64 images.

## Legacy endpoint

An older, non-OpenAI image endpoint remains available at `POST https://api.nebulablock.com/api/v1/images/generation`. It takes flat parameters — `prompt`, `negative_prompt`, `num_steps`, `guidance_scale`, `width`, `height`, `seed`, `image`, and `mask` — rather than `provider_options`. Prefer `/v1/images/generations` for new work.

## See also

* [Image Generation](/products/serverless-inference/image-generation)
* [Videos](/api-reference/inference-api/videos)
* [Model Catalog](/products/serverless-inference/model-catalog)


# Videos

Submit, poll, and stream asynchronous video generations on Nebula Block.

Generate video from a text prompt or an input image. Because generation is long-running, this API is asynchronous: creating a generation returns immediately, and you poll for the result.

For a walkthrough, see [Video Generation](/products/serverless-inference/video-generation).

## Create a video generation

### HTTP Request

`POST` `{API_URL}/videos/generations`

where `API_URL = https://inference.nebulablock.com/v1`.

### Body Parameters

#### model `string` *required*

The video model to use, for example `Google/veo-3.1-fast`. Must be a video model — passing a text or image model returns `400` with code `invalid_model_type`.

#### prompt `string` *required*

The text prompt describing the video.

#### n\_seconds `integer`

Duration of the generated video in seconds. Between `1` and `24`. Defaults to `5`.

#### size `string`

Output size in `WxH` form. Defaults to `1280x720`.

#### aspect\_ratio `string`

Aspect ratio of the output — `"16:9"`, `"9:16"`, or `"1:1"`.

#### resolution `string`

Output resolution — `"720p"`, `"1080p"`, or `"4k"`. Higher resolutions cost more.

#### image\_url `string`

Publicly reachable URL of the source image. **Required for image-to-video models** (those with `-i2v` in the model ID); omitting it returns `400` with code `missing_parameter`.

#### include\_audio `boolean`

Generate audio alongside the video. Supported by Veo models, and increases the cost of the generation.

#### seed `integer`

Seed for reproducible generation.

#### provider\_options `dict`

Provider-specific options passed through unchanged.

#### user `string`

An optional identifier for the end user making the request.

### Response Attributes

#### id `string`

The generation ID. Use it to poll for the result.

#### object `string`

Always `video.generation`.

#### created\_at `integer`

Unix timestamp of when the generation was created.

#### status `string`

One of `pending`, `in_progress`, `completed`, or `failed`.

#### model `string`

The resolved model name.

#### estimated\_cost `float`

The estimated cost of the generation in USD, returned when the job is created.

#### url `string`

Download URL for the finished video. Present only when `status` is `completed`.

#### error `dict`

Error details. Present only when `status` is `failed`.

### Example

#### Request

```bash
curl -X POST "https://inference.nebulablock.com/v1/videos/generations" \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $NEBULA_API_KEY" \
    --data-raw '{
        "model": "Google/veo-3.1-fast",
        "prompt": "A time-lapse of the Montreal skyline at sunset, cinematic, 35mm",
        "n_seconds": 5,
        "resolution": "720p"
    }'
```

#### Response

```json
{
  "id": "b3f1c0e2-6d1a-4e2b-9f77-6a1a2b3c4d5e",
  "object": "video.generation",
  "created_at": 1756944000,
  "status": "pending",
  "model": "Google/veo-3.1-fast",
  "estimated_cost": 0.6
}
```

## Retrieve a video generation

### HTTP Request

`GET` `{API_URL}/videos/generations/{generation_id}`

### Example

#### Request

```bash
curl "https://inference.nebulablock.com/v1/videos/generations/$GENERATION_ID" \
    -H "Authorization: Bearer $NEBULA_API_KEY"
```

#### Response

```json
{
  "id": "b3f1c0e2-6d1a-4e2b-9f77-6a1a2b3c4d5e",
  "object": "video.generation",
  "created_at": 1756944000,
  "status": "completed",
  "model": "Google/veo-3.1-fast",
  "url": "https://..."
}
```

## Stream generation progress

### HTTP Request

`GET` `{API_URL}/videos/generations/{generation_id}/stream`

Streams progress as Server-Sent Events until the generation reaches a terminal state. Use this instead of polling when you want to surface progress in a UI.

## Errors

| Status | Code                         | Meaning                                                                                    |
| ------ | ---------------------------- | ------------------------------------------------------------------------------------------ |
| `400`  | `model_not_found`            | The model ID does not exist                                                                |
| `400`  | `invalid_model_type`         | The model is not a video model                                                             |
| `400`  | `model_not_supported`        | The model is not currently dispatchable                                                    |
| `400`  | `missing_parameter`          | An `-i2v` model was called without `image_url`                                             |
| `402`  | `insufficient_credits`       | Your balance cannot cover the estimated cost                                               |
| `403`  | `enterprise_access_required` | The model is restricted to enterprise accounts                                             |
| `429`  | `rate_limit_exceeded`        | Daily or per-minute limit reached — see [Tiers and Rate Limits](/account/tiers-and-limits) |

## See also

* [Video Generation](/products/serverless-inference/video-generation)
* [Images](/api-reference/inference-api/images)
* [Model Catalog](/products/serverless-inference/model-catalog)


# Embeddings

Turn text into embedding vectors for semantic search and retrieval on Nebula Block.

Return the generated embeddings based on the given inputs.

## HTTP Request

`POST` `{API_URL}/embeddings`

where `API_URL = https://inference.nebulablock.com/v1`. The body requires:

* `model`: The model to use for generating embeddings.
* `input`: A list of strings to generate embeddings from.

For authentication, see the [Authentication](/api-reference/authentication) section. For an example, see the [Inference Models](/products/serverless-inference/embeddings) section.

## Response Attributes

#### model `model`

A string representing the AI model used to generate the response.

#### data `array`

An array containing the embeddings, represented by dictionaries with the following key-value pairs:

* **embedding** `list of floats`: The generated embedding for input at index `index`.
* **index** `integer`: An index to identify the position of the embedding in the response, relative to the ordering of the input.
* **object** `string`: An object label to describe the data.

#### object `string`

Describes the type of data returned.

#### usage `dict`

A dictionary containing information about the inference request, in key-value pairs:

* **completion\_tokens** `integer`: The number of tokens generated in the completion for a completion action (not applicable for embeddings).
* **prompt\_tokens** `integer`: The number of tokens in the prompt.
* **total\_tokens** `integer`: The total number of tokens (prompt and completion combined).
* **completion\_tokens\_details** `null`: Additional details about the completion tokens, if available.
* **prompt\_tokens\_details** `null`: Additional details about the prompt tokens, if available.

## Example

#### Request

```bash
curl -X POST '{API_URL}/embeddings' \
-H 'Authorization: Bearer {TOKEN/KEY}' \
-H 'Content-Type: application/json' \
-d '{
    "model": "Qwen/Qwen3-Embedding-8B",
    "input": [
        "Bananas are berries, but strawberries are not, according to botanical classifications.",
        "The Eiffel Tower in Paris was originally intended to be a temporary structure."
    ]
}'
```

#### Response

Here's an example of a successful response. `data` contains one entry per input string, each with its embedding vector and the `index` of the input it corresponds to.

```json
{
    "model": "Qwen/Qwen3-Embedding-8B",
    "data": [
        {
            "embedding": [
                -0.373046875,
                ...,
                -0.10302734375
            ],
            "index": 0,
            "object": "embedding"
        },
        {
            "embedding": [
                -0.50390625,
                ...,
                -0.03564453125,
                0.01409912109375
            ],
            "index": 1,
            "object": "embedding"
        }
    ],
    "object": "list",
    "usage": {
        "completion_tokens": 0,
        "prompt_tokens": 33,
        "total_tokens": 33,
        "completion_tokens_details": null,
        "prompt_tokens_details": null
    }
}
```

For more examples, see the [Inference Models](/products/serverless-inference/embeddings) section.


# Rerank

Score documents against a query and return them ranked by relevance.

Score a set of documents against a query and return them ordered by relevance. For how this fits into a retrieval pipeline, see [Reranking](/products/serverless-inference/reranking).

## HTTP Request

`POST` `{API_URL}/rerank`

where `API_URL = https://inference.nebulablock.com/v1`.

## Body Parameters

#### model `string` *required*

The reranking model to use, for example `BAAI/bge-reranker-v2-m3`.

#### query `string` *required*

The search query to score documents against.

#### documents `list` *required*

The list of documents to rerank.

#### top\_n `integer`

Return only the top N results. Defaults to returning every document.

#### return\_documents `boolean`

Include the document text in each result alongside its score.

#### rank\_fields `list`

For structured documents, the fields to rank on.

#### max\_tokens\_per\_doc `integer`

Truncate each document to this many tokens before scoring.

## Response Attributes

#### id `string`

Identifier for the reranking request.

#### results `list`

The reranked documents, ordered by descending relevance. Each entry contains:

* **index** `integer`: Position of the document in the `documents` array you sent.
* **relevance\_score** `float`: Relevance score, higher is more relevant.
* **document** `object`: `{"text": "..."}`, present when `return_documents` is `true`.

#### meta `dict`

Usage details for the request: **billed\_units** (`search_units`, `total_tokens`) and **tokens** (`input_tokens`, `output_tokens`).

## Example

#### Request

```bash
curl -X POST "https://inference.nebulablock.com/v1/rerank" \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $NEBULA_API_KEY" \
    --data-raw '{
        "model": "BAAI/bge-reranker-v2-m3",
        "query": "How do I rent a GPU by the hour?",
        "documents": [
            "Object Storage is an S3-compatible service for datasets and checkpoints.",
            "GPU instances are billed hourly and can be deployed in minutes from the console.",
            "Tier 3 requires a $10 deposit."
        ],
        "top_n": 2
    }'
```

#### Response

```json
{
  "id": "rerank-...",
  "results": [
    { "index": 1, "relevance_score": 0.98 },
    { "index": 2, "relevance_score": 0.41 }
  ]
}
```

## See also

* [Reranking](/products/serverless-inference/reranking)
* [Embeddings](/api-reference/inference-api/embeddings)
* [Model Catalog](/products/serverless-inference/model-catalog)


# Platform API

The Platform API for managing Nebula Block instances, SSH keys, API keys, object storage, and billing.

The Platform API manages everything that is not inference: compute instances, SSH keys, API keys, object storage, billing, and teams.

* **Base URL:** `https://api.nebulablock.com`
* **Base path:** `/api/v1`
* **`API_URL`:** `https://api.nebulablock.com/api/v1`
* **Authentication:** `Authorization: Bearer <token or API key>` — see [Authentication](/api-reference/authentication)

Responses share a common envelope: a `data` payload, a `message` string, and a `status` of `success` or `failed`. Some listing endpoints add a `meta` block for pagination.

> **Important:** Several endpoints report business failures as **HTTP 200 with `"status": "failed"`** — a duplicate name, an exceeded quota, or a rejected operation does not necessarily arrive as a 4xx. Check the `status` field, not just the HTTP status code. Endpoints that behave this way say so.

## Compute

| Endpoint                                                   | Reference                                                                                  |
| ---------------------------------------------------------- | ------------------------------------------------------------------------------------------ |
| `GET /computing/products`                                  | [List Products](/api-reference/platform-api/list-products)                                 |
| `GET /computing/images`                                    | [List OS Images](/api-reference/platform-api/list-products/list-os-images)                 |
| `POST /computing/instance`                                 | [Create Instance](/api-reference/platform-api/list-products/create-instance)               |
| `GET /computing/instances`                                 | [List Instances](/api-reference/platform-api/list-products/list-instances)                 |
| `GET /computing/deleted-instances`                         | [List Deleted Instances](/api-reference/platform-api/list-products/list-deleted-instances) |
| `GET /computing/instance/{id}`                             | [Get Instance](/api-reference/platform-api/list-products/get-instance)                     |
| `GET /computing/instance/{id}/start`                       | [Start Instance](/api-reference/platform-api/list-products/start-instance)                 |
| `GET /computing/instance/{id}/stop`                        | [Stop Instance](/api-reference/platform-api/list-products/stop-instance)                   |
| `GET /computing/instance/{id}/reboot`                      | [Reboot Instance](/api-reference/platform-api/list-products/reboot-instance)               |
| `DELETE /computing/instance/{id}`                          | [Delete Instance](/api-reference/platform-api/list-products/delete-instance)               |
| `GET /computing/instance/{id}/firewall-rules`              | [Firewall Rules](/api-reference/platform-api/list-products/firewall-rules)                 |
| `POST /computing/instance/{id}/firewall-rules`             | [Firewall Rules](/api-reference/platform-api/list-products/firewall-rules)                 |
| `DELETE /computing/instance/{id}/firewall-rules/{rule_id}` | [Firewall Rules](/api-reference/platform-api/list-products/firewall-rules)                 |

## SSH keys

| Endpoint                | Reference                                                                  |
| ----------------------- | -------------------------------------------------------------------------- |
| `GET /ssh-keys/`        | [List SSH Keys](/api-reference/platform-api/list-ssh-keys)                 |
| `POST /ssh-keys/`       | [Create SSH Key](/api-reference/platform-api/list-ssh-keys/create-ssh-key) |
| `PUT /ssh-keys/{id}`    | [Rename SSH Key](/api-reference/platform-api/list-ssh-keys/rename-ssh-key) |
| `DELETE /ssh-keys/{id}` | [Delete SSH Key](/api-reference/platform-api/list-ssh-keys/delete-ssh-key) |

## API keys

| Endpoint            | Reference                                                                  |
| ------------------- | -------------------------------------------------------------------------- |
| `GET /keys`         | [List API Keys](/api-reference/platform-api/list-api-keys)                 |
| `POST /keys`        | [Create API Key](/api-reference/platform-api/list-api-keys/create-api-key) |
| `PUT /keys/{id}`    | [Update API Key](/api-reference/platform-api/list-api-keys/update-api-key) |
| `DELETE /keys/{id}` | [Delete API Key](/api-reference/platform-api/list-api-keys/delete-api-key) |

## Billing

| Endpoint                                   | Reference                                                                                 |
| ------------------------------------------ | ----------------------------------------------------------------------------------------- |
| `GET /users/credits`                       | [Get Credit Balance](/api-reference/platform-api/get-credit-balance)                      |
| `GET /users/credits/history`               | [Get Payment History](/api-reference/platform-api/get-credit-balance/get-payment-history) |
| `GET /users/invoices`                      | [List Invoices](/api-reference/platform-api/get-credit-balance/list-invoices)             |
| `GET /users/invoice-download/{invoice_id}` | [Download Invoice](/api-reference/platform-api/get-credit-balance/download-invoice)       |

## Object storage

> **Note:** Workspace responses carry a `provider` field identifying the storage backend, and the console appends a matching `provider` query parameter to every object storage call. The parameter is not required — the endpoints behave the same without it — but you will see it in browser traffic.

| Endpoint                                      | Reference                                                                                  |
| --------------------------------------------- | ------------------------------------------------------------------------------------------ |
| `GET /object-storage/`                        | [List Storage Workspaces](/api-reference/platform-api/list-workspaces)                     |
| `POST /object-storage/`                       | [Create Storage Workspace](/api-reference/platform-api/list-workspaces/create-workspace)   |
| `DELETE /object-storage/`                     | [Delete Storage Workspace](/api-reference/platform-api/list-workspaces/delete-workspace)   |
| `POST /object-storage/regenerate-key-pair`    | [Regenerate Access Keys](/api-reference/platform-api/list-workspaces/regenerate-key-pair)  |
| `GET /object-storage/buckets`                 | [List Buckets](/api-reference/platform-api/list-workspaces/list-buckets)                   |
| `POST /object-storage/bucket`                 | [Create Bucket](/api-reference/platform-api/list-workspaces/create-bucket)                 |
| `DELETE /object-storage/bucket`               | [Delete Bucket](/api-reference/platform-api/list-workspaces/delete-bucket)                 |
| `GET /object-storage/bucket/files`            | [List Files](/api-reference/platform-api/list-workspaces/list-files)                       |
| `POST /object-storage/upload`                 | [Upload File](/api-reference/platform-api/list-workspaces/upload-file)                     |
| `GET /object-storage/download-url`            | [Get Download URL](/api-reference/platform-api/list-workspaces/get-download-url)           |
| `DELETE /object-storage/file`                 | [Delete File](/api-reference/platform-api/list-workspaces/delete-file)                     |
| `POST /object-storage/buckets/toggle-privacy` | [Toggle Bucket Privacy](/api-reference/platform-api/list-workspaces/toggle-bucket-privacy) |
| `GET /object-storage/usage-data`              | [Get Storage Usage](/api-reference/platform-api/list-workspaces/get-usage)                 |

## Not yet documented

These endpoints are live but do not have reference pages yet. Their shapes are visible in the console's network traffic, and the guides linked below cover the same features through the UI:

| Area                                 | Base path                                                       | Guide                                                                                                  |
| ------------------------------------ | --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
| Teams, members, roles, and team keys | `/teams`                                                        | [Teams](/account/teams)                                                                                |
| Usage and spend summaries            | `/usage`                                                        | —                                                                                                      |
| Account notifications                | `/notifications`                                                | —                                                                                                      |
| Webhook configuration                | `/webhook-configs`                                              | —                                                                                                      |
| Hardware store                       | `/hardware`                                                     | —                                                                                                      |
| Storage workspace details            | `/object-storage/details`                                       | [Object Storage](/products/object-storage)                                                             |
| Direct object download               | `/object-storage/download`, `/object-storage/download-resource` | [Get Download URL](/api-reference/platform-api/list-workspaces/get-download-url) covers the usual path |

## See also

* [Authentication](/api-reference/authentication)
* [Inference API](/api-reference/inference-api)
* [Glossary](/resources/glossary)


# Instances

List the GPU and CPU instance configurations available to rent, with hardware specs and hourly pricing.

Return a list of available GPU instance hardware configurations, which include GPUs, CPUs, RAM, and system disk. These instance configurations are referred to as products.

## HTTP Request

`GET` `{API_URL}/computing/products`

## Response Attributes

#### data `object`

Products are **grouped by region, then by GPU type** — not returned as a flat array:

```
data → "CANADA" → "H100" → [ product, product, … ]
```

Regions currently returned are `CANADA`, `US`, `FINLAND`, `FRANCE` and `NORWAY`.

Each product contains:

* **id** `string`: The product's unique identifier. Pass this as `product_id` to [Create Instance](/api-reference/platform-api/list-products/create-instance).
* **dc\_id** `number`: Identifier of the data center providing the product. Must match the `dc_id` of the OS image you deploy.
* **product\_type** `string`: The form factor — `Virtual Machine`, `Baremetal`, or `Container`.
* **country** `string`: The country the product is hosted in, for example `CANADA`.
* **region** `string`: The region within that country. Often the same as `country`, but can be more specific, for example `Montreal`.
* **price\_per\_hour** `decimal`: Hourly price in USD.
* **cpu** `number`: Number of CPU cores.
* **ram** `number`: RAM in gigabytes.
* **gpu** `string`: The full GPU model name, for example `A100-80G-PCIe`.
* **gpu\_type** `string`: The GPU family, which is also the grouping key — `H100`, `A100`, `L40`, `B200`, `B300`, `H200`, `RTX`.
* **gpu\_count** `number`: Number of GPUs in the configuration.
* **disk\_size** `number`: Root disk size in gigabytes.
* **ephemeral** `number`: Ephemeral disk capacity in gigabytes. Ephemeral storage is a temporary drive attached to the instance for the active workload; it does not survive termination.
* **stock** `number`: Units currently in stock.
* **is\_available** `boolean`: Whether the product can be deployed right now. Check this rather than `stock` — configurations can report stock while being unavailable.
* **is\_spot** `boolean`: Whether the product is spot capacity.
* **featured** `boolean`: Whether the console highlights this configuration.
* **type** `number`: An internal product classification. Usually `null`.

#### status `string`

Indicates the result of the request. `success` signifies success, while `failed` indicates an error.

#### message `string`

A description of the status of the request.

## Example

#### Request

```bash
curl -X GET '{API_URL}/computing/products' \
-H 'Authorization: Bearer {TOKEN/KEY}' \
-H 'Content-Type: application/json'
```

#### Response

```json
{
    "data": {
        "CANADA": {
            "H100": [
                {
                    "id": "b59cfc9f-8ab0-447f-8b2a-bb54e529d986",
                    "dc_id": 8,
                    "product_type": "Virtual Machine",
                    "country": "CANADA",
                    "region": "CANADA",
                    "price_per_hour": 2.632,
                    "cpu": 28,
                    "ram": 180,
                    "gpu": "H100-80G-PCIe",
                    "gpu_type": "H100",
                    "gpu_count": 1,
                    "disk_size": 100,
                    "ephemeral": 750,
                    "stock": 99,
                    "is_available": true,
                    "type": null,
                    "featured": false,
                    "is_spot": false
                },
                {
                    "id": "673d728d-1c84-4296-a79c-06014c27c9ff",
                    "dc_id": 8,
                    "product_type": "Virtual Machine",
                    "country": "CANADA",
                    "region": "CANADA",
                    "price_per_hour": 2.696,
                    "cpu": 28,
                    "ram": 180,
                    "gpu": "H100-80G-PCIe",
                    "gpu_type": "H100",
                    "gpu_count": 1,
                    "disk_size": 850,
                    "ephemeral": 0,
                    "stock": 99,
                    "is_available": true,
                    "type": null,
                    "featured": false,
                    "is_spot": false
                }
            ]
        },
        "US": {
            "B200": [
                {
                    "id": "a1d0180b-8228-4688-907c-36662bb1e641",
                    "dc_id": 7,
                    "product_type": "Virtual Machine",
                    "country": "US",
                    "region": "US",
                    "price_per_hour": 57.2,
                    "cpu": 160,
                    "ram": 1792,
                    "gpu": "B200-NVLink",
                    "gpu_type": "B200",
                    "gpu_count": 8,
                    "disk_size": 2048,
                    "ephemeral": 4092,
                    "stock": 99,
                    "is_available": true,
                    "type": null,
                    "featured": true,
                    "is_spot": false
                }
            ]
        }
    },
    "message": "Successfully get all products",
    "status": "success"
}
```


# List OS Images

List the operating system images you can deploy a Nebula Block instance with.

Return a list of all available operating system images, including details about each image's version and driver, if applicable.

## HTTP Request

`GET` `{API_URL}/computing/images`

## Response Attributes

#### data `object`

Images are **grouped by region**, not returned as a flat array:

```
data → "CANADA" → [ image, image, … ]
```

More regions appear here than in [List Products](/api-reference/platform-api/list-products), and one key may be `null` for images not tied to a region.

Each image contains:

* **id** `string`: The image's unique identifier. Pass this as `image_id` to [Create Instance](/api-reference/platform-api/list-products/create-instance).
* **dc\_id** `number`: Identifier of the data center holding the image. **Must match the `dc_id` of the product you deploy** — an image and a product from different data centers cannot be combined.
* **os\_name** `string`: The full image name, for example `Ubuntu Server 22.04 LTS R535 CUDA 12.2`.
* **os\_type** `string`: The operating system family, for example `Ubuntu`.
* **region** `string`: The region the image is available in.

#### status `string`

Indicates the result of the request. `success` signifies success, while `failed` indicates an error.

#### message `string`

A description of the status of the request.

## Example

#### Request

```bash
curl -X GET '{API_URL}/computing/images' \
-H 'Authorization: Bearer {TOKEN/KEY}' \
-H 'Content-Type: application/json'
```

#### Response

```json
{
    "data": {
        "CANADA": [
            {
                "id": "fcp66d566c93a95010012",
                "dc_id": 1,
                "os_name": "Ubuntu Server 22.04 LTS",
                "os_type": "Ubuntu",
                "region": "CANADA"
            },
            {
                "id": "5d062858-4362-4246-8a63-f049b73e3cb0",
                "dc_id": 2,
                "os_name": "Ubuntu Server 22.04 LTS R535 CUDA 12.2",
                "os_type": "Ubuntu",
                "region": "CANADA"
            }
        ],
        "US": [
            {
                "id": "f7878dc2-23c0-4131-a93d-67a6b54bfca7",
                "dc_id": 2,
                "os_name": "Ubuntu Server 22.04 LTS R535 CUDA 12.2",
                "os_type": "Ubuntu",
                "region": "US"
            }
        ]
    },
    "message": "Successfully get all images",
    "status": "success"
}
```


# Create Instance

Deploy a new GPU or CPU instance with your chosen hardware, OS image, and SSH key.

Create an instance with the specified custom configuration and features provided in the request body.

## HTTP Request

`POST` `{API_URL}/computing/instance`

## Body parameters

| Parameter       | Requirement | Type     | Description                                                                                                                                                              |
| --------------- | ----------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `instance_name` | Required    | `string` | Name for the instance. Letters, digits, `.` and `-` only — the pattern `^[a-zA-Z0-9.-]+$` is enforced, so spaces and underscores are rejected                            |
| `product_id`    | Required    | `string` | The hardware configuration to deploy, from [List Products](/api-reference/platform-api/list-products)                                                                    |
| `image_id`      | Required    | `string` | The OS image to install, from [List OS Images](/api-reference/platform-api/list-products/list-os-images)                                                                 |
| `ssh_key_id`    | Optional    | `string` | UUID of the SSH key to authorise, from [List SSH Keys](/api-reference/platform-api/list-ssh-keys). Omit only if the configuration issues a username and password instead |
| `port_list`     | Optional    | `list`   | Ports to expose. Container deployments only                                                                                                                              |
| `env`           | Optional    | `object` | Environment variables as string key/value pairs. Container deployments only                                                                                              |
| `cmd`           | Optional    | `string` | Command to run in the container. Container deployments only                                                                                                              |

> **Note:** `image_id` and `product_id` must be from the same data center (`dc_id`) and region.

> **Note:** `port_list`, `env` and `cmd` apply to container deployments and are ignored for virtual machines and bare metal.

## Response Attributes

#### message `string`

A description of the status of the request.

#### status `string`

Indicates the result of the request. **success** signifies success, while **failed** indicates an error.

## Example

#### Request

```bash
curl -X POST '{API_URL}/computing/instance' \
-H 'Authorization: Bearer {TOKEN/KEY}' \
-H 'Content-Type: application/json' \
-d '{
    "instance_name":"testname",
    "product_id":"fcp66d566c43a9501001256",
    "image_id":"fcp66d566c93a95010012",
    "ssh_key_id":2
}'
```

#### Response

```json
{
    "message": "Instances created successfully",
    "status": "success"
}

```


# List Instances

List the instances currently running on your Nebula Block account.

Return a list of all active instances.

## HTTP Request

`GET` `{API_URL}/computing/instances`

## Query Parameters

| Parameter | Requirement | Type  | Description                                                                                                                                                    |
| --------- | ----------- | ----- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `offset`  | Optional    | `int` | **Page number**, starting at `1`. Despite the name this is not a row offset — the API computes `(offset - 1) * limit` internally. Defaults to `1`, minimum `1` |
| `limit`   | Optional    | `int` | Results per page. Defaults to `10`, maximum `100`                                                                                                              |
| `team_id` | Optional    | `int` | Return a team's instances instead of your own. See [Teams](/account/teams)                                                                                     |
| `type`    | Optional    | `int` | Filter by product type                                                                                                                                         |

## Response Attributes

#### data `array`

A flat array of your current instances. Empty, with `status` still `success`, when there are none.

Each entry contains:

* **id** `string`: The unique identifier for the product.
* **region** `string`: The region where the GPU product is available.
* **product\_type** `string`: The type of instance,like GPU and CPU.
* **host\_name** `string`: The user defined name of the instance.
* **cpu\_cores** `number`: The number of CPU cores in the product.
* **ram** `number`: The amount of RAM in gigabytes for the product.
* **gpu** `string`: The GPU model name for the GPU product.
* **gpu\_type** `string`: The GPU serial name for the GPU product.
* **gpu\_count**: The number of GPUs included in the GPU product.
* **disk\_size** `number`: The root disk size of the GPU instance in gigabytes.
* **ephemeral** `number`: The ephemeral disk size of the GPU instance in gigabytes.
* **public\_ipv4** `string`: New billing cycle, the default is hourly.
* **price\_per\_hour** `string`: The price per hour of the instance.
* **os** `string`: The operation system of the instance.
* **status** `string`: The status of the instance.

#### message `string`

A description of the status of the request.

#### total\_instance `number`

The total number of matching instances, for pagination. This sits **alongside** `data` at the top level of the response, not inside it.

#### status `string`

Indicates the result of the request.\
**success** signifies success, while **failed** indicates an error.

## Example

#### Request

```bash
curl -X GET '{API_URL}/computing/instances' \
-H 'Authorization: Bearer {ACCESS_TOKEN}' \
-H 'Content-Type: application/json' \
```

#### Response

```json
{
    "data": [
        {
            "id": "102cade84ea-e703-4400-b77d-8ed545d198ee",
            "region": "CANADA",
            "product_type": "GPU",
            "host_name": "demo",
            "cpu_cores": 28,
            "ram": 58,
            "gpu_type": "RTX-A6000",
            "gpu_count": 1,
            "disk_size": 100,
            "ephemeral": 1500,
            "public_ipv4": "38.80.81.128",
            "price_per_hour": 0.679,
            "os": "Ubuntu Server 20.04 LTS (Focal Fossa)",
            "status": "Running"
        }
    ],
    "total_instance": 1,
    "message": "All instances retrieved successfully",
    "status": "success"
}

```


# List Deleted Instances

List instances that have been deleted from your Nebula Block account.

Return a list of all deleted instances.

## HTTP Request

`GET` `{API_URL}/computing/deleted-instances`

## Query Parameters

| Parameter | Requirement | Type  | Description                                                                                                                                                    |
| --------- | ----------- | ----- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `offset`  | Optional    | `int` | **Page number**, starting at `1`. Despite the name this is not a row offset — the API computes `(offset - 1) * limit` internally. Defaults to `1`, minimum `1` |
| `limit`   | Optional    | `int` | Results per page. Defaults to `10`, maximum `100`                                                                                                              |
| `team_id` | Optional    | `int` | Return a team's instances instead of your own. See [Teams](/account/teams)                                                                                     |
| `type`    | Optional    | `int` | Filter by product type                                                                                                                                         |

## Response Attributes

#### data `array`

A flat array of instances that have been deleted from your account. Empty, with `status` still `success`, when there are none.

Each entry contains:

* **id** `string`: The unique identifier for the product.
* **region** `string`: The region where the GPU product is available.
* **product\_type** `string`: The type of instance,like GPU and CPU.
* **host\_name** `string`: The user defined name of the instance.
* **cpu\_cores** `number`: The number of CPU cores in the product.
* **ram** `number`: The amount of RAM in gigabytes for the product.
* **gpu** `string`: The GPU model name for the GPU product.
* **gpu\_type** `string`: The GPU serial name for the GPU product.
* **gpu\_count**: The number of GPUs included in the GPU product.
* **disk\_size** `number`: The root disk size of the GPU instance in gigabytes.
* **ephemeral** `number`: The ephemeral disk size of the GPU instance in gigabytes.
* **public\_ipv4** `string`: New billing cycle, the default is hourly.
* **price\_per\_hour** `string`: The price per hour of the instance.
* **os** `string`: The operation system of the instance.
* **status** `string`: The status of the instance.

#### message `string`

A description of the status of the request.

#### total\_instance `number`

The total number of matching instances, for pagination. This sits **alongside** `data` at the top level of the response, not inside it.

#### status `string`

Indicates the result of the request.\
**success** signifies success, while **failed** indicates an error.

## Example

#### Request

```bash
curl -X GET '{API_URL}/computing/deleted-instances' \
-H 'Authorization: Bearer {ACCESS_TOKEN}' \
-H 'Content-Type: application/json' \
```

#### Response

```json
{
    "data": [
        {
            "id": "102cade84ea-e703-4400-b77d-8ed545d198ee",
            "region": "CANADA",
            "product_type": "GPU",
            "host_name": "demo",
            "cpu_cores": 28,
            "ram": 58,
            "gpu_type": "RTX-A6000",
            "gpu_count": 1,
            "disk_size": 100,
            "ephemeral": 1500,
            "public_ipv4": "38.80.81.128",
            "price_per_hour": 0.679,
            "os": "Ubuntu Server 20.04 LTS (Focal Fossa)",
            "status": "Deleted"
        }
    ],
    "total_instance": 1,
    "message": "All deleted instances retrieved successfully",
    "status": "success"
}

```


# Get Instance

Retrieve the full details of one instance, including its connection credentials.

Return instance detail information, like cpu, gpu, ram, total running time and etc.

## HTTP Request

`GET` `{API_URL}/computing/instance/{id}`

## Path parameters

| Parameters | Requirements | Type     | Description                                                                        |
| ---------- | ------------ | -------- | ---------------------------------------------------------------------------------- |
| id         | Required     | `string` | The unique identifier of the instance. `{id} comes from <List User Instances API>` |

## Response Attributes

#### data `dict`

An object describing the instance:

* **id** `string`: The unique identifier for the product.
* **region** `string`: The region where the GPU product is available.
* **product\_type** `string`: The type of instance,like GPU and CPU.
* **host\_name** `string`: The user defined name of the instance.
* **cpu\_cores** `number`: The number of CPU cores in the product.
* **ram** `number`: The amount of RAM in gigabytes for the product.
* **gpu** `string`: The GPU model name for the GPU product.
* **gpu\_type** `string`: The GPU serial name for the GPU product.
* **gpu\_count**: The number of GPUs included in the GPU product.
* **disk\_size** `number`: The root disk size of the GPU instance in gigabytes.
* **ephemeral** `number`: The ephemeral disk size of the GPU instance in gigabytes.
* **public\_ipv4** `string`: The Public IPv4 address associated with the instance.
* **lan\_ipv4** `string`: The LAN IPv4 address associated with the instance.
* **login\_method** `string`: The login method of the instance.
* **os** `string`: The operation system of the instance.
* **exposed\_ports** `string`: The exposed ports of the container instance.
* **user\_name** `string`: The user name of the container instance.
* **password** `string`: The password of the container instance.
* **status** `string`: The status of the instance.
* **start\_time** `string`: The time that instance started.
* **running\_time** `string`: The total running time of the instance.
* **total\_cost** `string`: The total cost of the instance.

#### message `string`

A description of the status of the request.

* **dc\_id** `number`: Identifier of the data center hosting the instance.
* **image** `string`: The OS image the instance was deployed from.
* **created\_at** `string`: When the instance record was created.
* **started\_at** `string`: When the instance last started.
* **ended\_at** `string`: When the instance was terminated, or `null` while it is alive.
* **firewall\_supported** `boolean`: Whether this instance supports [firewall rules](/api-reference/platform-api/list-products/firewall-rules). Not every configuration does.
* **is\_spot** `boolean`: Whether the instance is running on spot capacity.
* **bandwidth** `number`: Network bandwidth allocated to the instance.
* **cpu\_count** `number`: Number of CPUs, alongside `cpu_cores`.
* **cpu\_model** `string`: The CPU model.
* **description** `string`: The instance description, if one was set.
* **team\_id** `number`: The owning team, or `null` for a personal instance.

> **Note:** The response also carries fields used by the console UI, such as `capabilities` and `cmd_log`. Treat anything not listed here as internal and subject to change.

#### status `string`

Indicates the result of the request.\
**success** signifies success, while **failed** indicates an error.

## Example

#### Request

```bash
curl -X GET '{API_URL}/computing/instance/{id}' \
-H 'Authorization: Bearer {ACCESS_TOKEN}' \
-H 'Content-Type: application/json' \

```

#### Response

```json
{
    "data": [
        {
            "id": "102cade84ea-e703-4400-b77d-8ed545d198ee",
            "region": "CANADA",
            "product_type": "Virtual Machine",
            "host_name": "demo",
            "cpu_cores": "28",
            "ram": "58",
            "gpu_type": "RTX-A6000",
            "gpu_count": 1,
            "disk_size": 100,
            "public_ipv4": "38.80.81.128",
            "login_method": "",
            "os": "Ubuntu Server 20.04 LTS (Focal Fossa)",
            "exposed_ports": "",
            "vm_name": "demo",
            "vm_password": "qZ3!Xukz=I-Xv_ya",
            "status": "Running",
            "start_time": "EST 2024-11-04 10:11:50",
            "running_time": "0.0000 hours",
            "total_cost": "$0.0000"
        }
    ],
    "message": "Get instance detail successfully",
    "status": "success"
}

```


# Start Instance

Power on a stopped Nebula Block instance.

Initiate the startup of an instance. Provide the instance ID in the path to start the specified instance.

## HTTP Request

`GET` `{API_URL}/computing/instance/{id}/start`

## Path parameters

| Parameters | Requirements | Type     | Description                                                                        |
| ---------- | ------------ | -------- | ---------------------------------------------------------------------------------- |
| id         | Required     | `string` | The unique identifier of the instance. `{id} comes from <List User Instances API>` |

> **Important:** The instance must be in `Stopped` or `Preempted` state. Calling this on an instance in any other state returns **HTTP 200** with `"status": "failed"` and the message `"Instance status is invalid for start operation"` — check `status`, not the HTTP code.

## Response Attributes

#### data `list`

Always empty on this endpoint.

#### message `string`

A description of the status of the request.

#### status `string`

Indicates the result of the request. `success` signifies success, while `failed` indicates an error.

## Example

#### Request

```bash
curl -X GET '{API_URL}/computing/instance/{id}/start' \
-H 'Authorization: Bearer {ACCESS_TOKEN}' \
-H 'Content-Type: application/json' \

```

#### Response

```json
{
    "message": "Instances started successfully",
    "status": "success"
}
```


# Stop Instance

Power off a running Nebula Block instance. Billing continues while the instance exists.

Shut down an instance. Provide the instance ID in the path to initiate the shutdown process for that instance.

## HTTP Request

`GET` `{API_URL}/computing/instance/{id}/stop`

## Path parameters

| Parameters | Requirements | Type     | Description                                                                        |
| ---------- | ------------ | -------- | ---------------------------------------------------------------------------------- |
| id         | Required     | `string` | The unique identifier of the instance. `{id} comes from <List User Instances API>` |

> **Important:** The instance must be in `Running` state. Calling this on an instance in any other state returns **HTTP 200** with `"status": "failed"` and the message `"Instance status is invalid for stop operation"` — check `status`, not the HTTP code.

## Response Attributes

#### data `list`

Always empty on this endpoint.

#### message `string`

A description of the status of the request.

#### status `string`

Indicates the result of the request. `success` signifies success, while `failed` indicates an error.

## Example

#### Request

```bash
curl -X GET '{API_URL}/computing/instance/{id}/stop' \
-H 'Authorization: Bearer {ACCESS_TOKEN}' \
-H 'Content-Type: application/json' \

```

#### Response

```json
{
    "message": "Instances stopped successfully",
    "status": "success"
}
```


# Reboot Instance

Reboot a running Nebula Block GPU or CPU instance without terminating it.

Initiate a reboot of an instance. Provide the instance ID in the path to reboot the specified instance.

## HTTP Request

`GET` `{API_URL}/computing/instance/{id}/reboot`

## Path parameters

| Parameters | Requirements | Type     | Description                                                                        |
| ---------- | ------------ | -------- | ---------------------------------------------------------------------------------- |
| id         | Required     | `string` | The unique identifier of the instance. `{id} comes from <List User Instances API>` |

> **Important:** The instance must be in `Running` or `Stopped` state. Calling this on an instance in any other state returns **HTTP 200** with `"status": "failed"` and the message `"Instance status is invalid for reboot operation"` — check `status`, not the HTTP code.

## Response Attributes

#### data `list`

Always empty on this endpoint.

#### message `string`

A description of the status of the request.

#### status `string`

Indicates the result of the request. `success` signifies success, while `failed` indicates an error.

## Example

#### Request

```bash
curl -X GET '{API_URL}/computing/instance/{id}/reboot' \
-H 'Authorization: Bearer {ACCESS_TOKEN}' \
-H 'Content-Type: application/json' \

```

#### Response

```json
{
    "message": "Instances rebooted successfully",
    "status": "success"
}
```


# Delete Instance

Permanently terminate a Nebula Block instance and stop its hourly billing.

Permanently delete an instance by specifying the instance ID in the path to delete the selected instance.

## HTTP Request

`DELETE` `{API_URL}/computing/instance/{id}`

## Path parameters

| Parameters | Requirements | Type     | Description                                                                        |
| ---------- | ------------ | -------- | ---------------------------------------------------------------------------------- |
| id         | Required     | `string` | The unique identifier of the instance. `{id} comes from <List User Instances API>` |

## Response Attributes

#### status `string`

Indicates the result of the request. `success` signifies success, while `failed` indicates an error.

#### message `string`

A description of the status of the request.

## Example

#### Request

```bash
curl -X DELETE '{API_URL}/computing/instance/{id}' \
-H 'Authorization: Bearer {TOKEN/KEY}' \
-H 'Content-Type: application/json' \
```

#### Response

```json
{
    "message": "Instances deleted successfully",
    "status": "success"
}

```


# Firewall Rules

List, add, and delete per-instance firewall rules on a Nebula Block GPU or CPU instance.

Each instance has its own set of firewall rules controlling which traffic reaches it. Rules are managed per instance, addressed by the instance's UUID.

> **Important:** **Not every instance supports firewall rules** — it depends on the instance's configuration. Check `firewall_supported` on [Get Instance](/api-reference/platform-api/list-products/get-instance), or the `supported` flag that the list endpoint below returns, before building on these endpoints.

## List firewall rules

### HTTP Request

`GET` `{API_URL}/computing/instance/{instance_uuid}/firewall-rules`

where `API_URL = https://api.nebulablock.com/api/v1`.

### Response Attributes

#### data `dict`

* **supported** `boolean`: Whether firewall rules are available on this instance.
* **rules** `list`: The instance's current rules. Always empty when `supported` is `false`.

#### status `string`

`success` or `failed`.

#### message `string`

A description of the result.

> **Important:** When firewall rules are not supported, this endpoint still returns **HTTP 200 with `"status": "success"`** and `data: {"supported": false, "rules": []}`. That is indistinguishable from a supported instance with no rules if you only look at `status` — **read `supported`**.

### Example

```bash
curl -X GET '{API_URL}/computing/instance/{instance_uuid}/firewall-rules' \
-H 'Authorization: Bearer {TOKEN}'
```

## Add a firewall rule

### HTTP Request

`POST` `{API_URL}/computing/instance/{instance_uuid}/firewall-rules`

### Body Parameters

| Parameter          | Requirement | Type      | Description                                               |
| ------------------ | ----------- | --------- | --------------------------------------------------------- |
| `direction`        | Required    | `string`  | `inbound` or `outbound`                                   |
| `protocol`         | Required    | `string`  | `tcp`, `udp`, `icmp`, or `any`                            |
| `ethertype`        | Optional    | `string`  | `IPv4` or `IPv6`. Defaults to `IPv4`                      |
| `remote_ip_prefix` | Optional    | `string`  | The CIDR the rule applies to. Defaults to `0.0.0.0/0`     |
| `port_range_min`   | Conditional | `integer` | Start of the port range. **Required for `tcp` and `udp`** |
| `port_range_max`   | Conditional | `integer` | End of the port range. **Required for `tcp` and `udp`**   |
| `description`      | Optional    | `string`  | A note describing what the rule is for                    |

Validation to be aware of, since these are rejected before the rule is created:

* `remote_ip_prefix` must be a valid CIDR, and its IP version must match `ethertype` — an IPv6 CIDR with `ethertype: IPv4` is refused.
* `port_range_min` and `port_range_max` are mandatory for `tcp` and `udp` rules, must be supplied together, must each fall within `1`–`65535`, and `port_range_min` cannot exceed `port_range_max`.

> **Important:** The instance must be `Running` or `Stopped`. Adding a rule to an instance in any other state — while it is still deploying, for instance — returns **HTTP 200 with `"status": "failed"`** and `"Instance status is invalid for firewall operations"`, so the rule is silently not applied.

> **Note:** On an instance where firewall rules are not available, this returns **HTTP 200 with `"status": "failed"`** and `"Firewall rules are not supported for this instance"`. The same applies to deleting a rule.

### Example

```bash
curl -X POST '{API_URL}/computing/instance/{instance_uuid}/firewall-rules' \
-H 'Authorization: Bearer {TOKEN}' \
-H 'Content-Type: application/json' \
-d '{
    "direction": "inbound",
    "protocol": "tcp",
    "ethertype": "IPv4",
    "remote_ip_prefix": "203.0.113.0/24",
    "port_range_min": 22,
    "port_range_max": 22,
    "description": "SSH from the office"
}'
```

> **Important:** Instances default to being reachable from anywhere on the ports their image opens. Narrow `remote_ip_prefix` to the addresses you actually connect from rather than leaving `0.0.0.0/0`.

## Delete a firewall rule

### HTTP Request

`DELETE` `{API_URL}/computing/instance/{instance_uuid}/firewall-rules/{rule_id}`

### Example

```bash
curl -X DELETE '{API_URL}/computing/instance/{instance_uuid}/firewall-rules/{rule_id}' \
-H 'Authorization: Bearer {TOKEN}'
```

## See also

* [Get Instance](/api-reference/platform-api/list-products/get-instance)
* [GPU Cloud](/products/gpu-cloud)


# SSH Keys

List the SSH public keys registered on your Nebula Block account.

Retrieves a list of your SSH keys.

## HTTP Request

`GET` `{API_URL}/ssh-keys`

## Query Parameters

| Parameters | Requirements | Type  | Description                                                   |
| ---------- | ------------ | ----- | ------------------------------------------------------------- |
| limit      | Optional     | `int` | The limit to the number of SSH keys returned. Defaults to 100 |
| offset     | Optional     | `int` | The offset of the returned SSH key response. Defaults to 0    |

## Response Attributes

#### data `dict`

Returns the `data` dictionary containing the total number of your SSH keys `total_ssh_keys` and the details of each SSH key as per your `limit` and `offset` in `ssh_keys`.

Each SSH key in `ssh_keys` has the following properties:

* `id`: The ID of the SSH key. This is the ID field that is used for the [Delete SSH Key](/api-reference/platform-api/list-ssh-keys/delete-ssh-key) endpoint.
* `key_name`: The name of the SSH key.
* `key_data`: The SSH key value.
* `create_time`: When the key was created, as an **Eastern Time** datetime string. Note this differs from [Create SSH Key](/api-reference/platform-api/list-ssh-keys/create-ssh-key) and [Rename SSH Key](/api-reference/platform-api/list-ssh-keys/rename-ssh-key), which return the raw UNIX timestamp.

#### status `string`

Indicates the result of the request to list your SSH keys. `success` signifies success, while `failed` indicates an error.

#### message `string`

A description of the status of the request.

## Example

#### Request

```bash
curl -X GET '{API_URL}/ssh-keys' \
-H 'Authorization: Bearer {TOKEN/KEY}'
```

#### Response

```json
{
    "data": {
        "total_ssh_keys": 1,
        "ssh_keys": [
            {
                "id": 75,
                "key_name": "My Personal SSH Key 1",
                "key_data": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD5",
                "create_time": "EST 2024-10-23 10:24:21"
            },
            {
                "id": 76,
                "key_name": "My Personal SSH Key 2",
                "key_data": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD5",
                "create_time": "EST 2024-10-24 10:24:21"
            }
        ]
    },
    "message": "SSH keys retrieved successfully",
    "status": "success"
}
```


# Create SSH Key

Register an SSH public key so you can log into your GPU instances.

Creates an SSH key for use in your instances.

## HTTP Request

`POST` `{API_URL}/ssh-keys`

## Body Parameters

| Parameters | Requirements | Type     | Description             |
| ---------- | ------------ | -------- | ----------------------- |
| key\_name  | Required     | `string` | The name of the SSH key |
| key\_data  | Required     | `string` | The SSH key value       |

## Response Attributes

#### data `dict`

Returns the `data` object, containing details of the new SSH Key.

Each SSH key specifies the following properties:

* `id`: The ID of the SSH key.
* `key_name`: The name of the SSH key.
* `key_data`: The SSH key value.
* `create_time`: The UNIX timestamp of when the key was created. [List SSH Keys](/api-reference/platform-api/list-ssh-keys) converts this to an Eastern Time string, so the two endpoints report it differently.

#### status `string`

Indicates the result of the request to create a SSH key. `success` signifies success, while `failed` indicates an error.

#### message `string`

A description of the status of the request.

## Example

#### Request

```bash
curl -X POST '{API_URL}/ssh-keys' \
-H 'Authorization: Bearer {TOKEN/KEY}' \
-d '{
    "name": "My Personal SSH Key",
    "key_data": "ssh-rsa AAADB3NzaC1yc2EBBACCAQABAAABAQD5",
}'
```

#### Response

```json
{
    "data": {
        "id": 73,
        "key_name": "My Personal SSH Key",
        "key_data": "ssh-rsa AAADB3NzaC1yc2EBBACCAQABAAABAQD5",
        "create_time": "1730847667"
    },
    "message": "SSH key created successfully",
    "status": "success"
}
```


# Rename SSH Key

Rename an SSH public key registered on your Nebula Block account.

Updates the name of a specified SSH key. Include the ID of the SSH key in the endpoint path and the new name in the body of the request. To retrieve your SSH key IDs, see the [List SSH Keys API](/api-reference/platform-api/list-ssh-keys).

## HTTP Request

`PUT` `{API_URL}/ssh-keys/{id}`

## Path Parameters

| Parameters | Requirements | Type  | Description                                        |
| ---------- | ------------ | ----- | -------------------------------------------------- |
| id         | Required     | `int` | The unique identifier of the SSH key to be renamed |

## Body Parameters

| Parameters | Requirements | Type     | Description                 |
| ---------- | ------------ | -------- | --------------------------- |
| key\_name  | Required     | `string` | The new name of the SSH key |

## Response Attributes

#### data `dict`

Returns the `data` object, containing details of the updated SSH Key.

Each updated SSH key specifies the following properties:

* `id`: The ID of the SSH key.
* `key_name`: The new name of the SSH key.
* `key_data`: The SSH key value.
* `create_time`: The UNIX timestamp of when the key was created. [List SSH Keys](/api-reference/platform-api/list-ssh-keys) converts this to an Eastern Time string, so the two endpoints report it differently.

#### status `string`

Indicates the result of the request to rename a SSH key. `success` signifies success, while `failed` indicates an error.

#### message `string`

A description of the status of the request.

## Example

#### Request

```bash
curl -X PUT '{API_URL}/ssh-keys/76' \
-H 'Authorization: Bearer {TOKEN/KEY}' \
-d '{
    "key_name": "Test user was here",
}'
```

#### Response

```json
{
    "data": {
        "id": 76,
        "key_name": "Test user was here",
        "key_data": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD5",
        "create_time": "1730847956"
    },
    "message": "SSH key updated successfully",
    "status": "success"
}
```


# Delete SSH Key

Delete an SSH public key from your Nebula Block account.

Deletes a specified SSH key by including the ID of the SSH key in the endpoint path. To retrieve your SSH key IDs, see the [List SSH Keys API](/api-reference/platform-api/list-ssh-keys).

## HTTP Request

`DELETE` `{API_URL}/ssh-keys/{id}`

## Path Parameters

| Parameters | Requirements | Type  | Description                                        |
| ---------- | ------------ | ----- | -------------------------------------------------- |
| id         | Required     | `int` | The unique identifier of the SSH key to be deleted |

## Response Attributes

#### data `dict`

Empty `data` object

#### status `string`

Indicates the result of the request to delete a SSH key. `success` signifies success, while `failed` indicates an error.

#### message `string`

A description of the status of the request.

## Example

#### Request

```bash
curl -X DELETE '{API_URL}/ssh-keys/5' \
-H 'Authorization: Bearer {TOKEN/KEY}'
```

#### Response

```json
{
    "data": {},
    "message": "SSH key deleted successfully",
    "status": "success"
}
```


# API Keys

Retrieve every API key on your Nebula Block account, including its name, status, and team.

Retrieve every API key on your account.

## HTTP Request

`GET` `{API_URL}/keys`

where `API_URL = https://api.nebulablock.com/api/v1`.

## Response Attributes

#### data `list`

An array of your API keys. Each key has the following properties:

* `id` `integer`: The key's ID. Use it with [Update API Key](/api-reference/platform-api/list-api-keys/update-api-key) and [Delete API Key](/api-reference/platform-api/list-api-keys/delete-api-key).
* `name` `string`: The name you gave the key.
* `key` `string`: The key value.
* `status` `integer`: `1` when the key is enabled, `0` when it is disabled.
* `created_at` `integer`: Unix timestamp of when the key was created.
* `team` `object`: The team the key belongs to, or `null` for a personal key. Contains `id`, `name`, and `description`.

#### status `string`

`success` or `failed`.

#### message `string`

A description of the result.

## Example

#### Request

```bash
curl -X GET '{API_URL}/keys' \
-H 'Authorization: Bearer {TOKEN}'
```

#### Response

```json
{
    "data": [
        {
            "id": 5,
            "name": "production",
            "key": "sk-...",
            "status": 1,
            "created_at": 1756944000,
            "team": null
        },
        {
            "id": 6,
            "name": "ci",
            "key": "sk-...",
            "status": 0,
            "created_at": 1756950000,
            "team": {"id": 2, "name": "Platform", "description": "Infra team"}
        }
    ],
    "message": "API keys successfully retrieved",
    "status": "success"
}
```

## See also

* [Create API Key](/api-reference/platform-api/list-api-keys/create-api-key)
* [Update API Key](/api-reference/platform-api/list-api-keys/update-api-key)
* [Delete API Key](/api-reference/platform-api/list-api-keys/delete-api-key)


# Create API Key

Create a new Nebula Block API key, optionally scoped to a team.

Create a new API key. To learn how to authenticate requests with it, see [Authentication](/api-reference/authentication).

## HTTP Request

`POST` `{API_URL}/keys`

where `API_URL = https://api.nebulablock.com/api/v1`.

## Body Parameters

| Parameter     | Requirement | Type      | Description                                                                               |
| ------------- | ----------- | --------- | ----------------------------------------------------------------------------------------- |
| `name`        | Required    | `string`  | A name for the API key                                                                    |
| `description` | Optional    | `string`  | A description of what the key is for                                                      |
| `team_id`     | Optional    | `integer` | Create the key under a team instead of your personal account. See [Teams](/account/teams) |

## Response Attributes

#### data `dict`

Contains the new key:

* `id` `integer`: The key's ID.
* `key` `string`: The key value used to authenticate requests.

#### status `string`

`success` or `failed`.

#### message `string`

A description of the result.

> **Note:** Creating a key notifies your account. There is a limit on how many keys one account can hold — if you hit it, contact support to have it raised.

## Example

#### Request

```bash
curl -X POST '{API_URL}/keys' \
-H 'Authorization: Bearer {TOKEN}' \
-H 'Content-Type: application/json' \
-d '{
    "name": "production",
    "description": "Key used by the production service"
}'
```

#### Response

```json
{
    "data": {
        "id": 5,
        "key": "sk-..."
    },
    "message": "New API key generated successfully",
    "status": "success"
}
```

## See also

* [List API Keys](/api-reference/platform-api/list-api-keys)
* [Delete API Key](/api-reference/platform-api/list-api-keys/delete-api-key)


# Update API Key

Change an API key's description, or disable and re-enable it.

Change an API key's description, or disable and re-enable it.

> **Important:** Use the [API Keys](https://console.nebulablock.com/apiKeys) page in the console to rename, disable or re-enable a key. This endpoint is documented here for completeness, but it is not currently a reliable way to do it — see [Known issues](#known-issues).

## HTTP Request

`PUT` `{API_URL}/keys/{key_id}`

where `API_URL = https://api.nebulablock.com/api/v1`.

## Path Parameters

| Parameter | Requirement | Type      | Description                                                                        |
| --------- | ----------- | --------- | ---------------------------------------------------------------------------------- |
| `key_id`  | Required    | `integer` | The ID of the key, from [List API Keys](/api-reference/platform-api/list-api-keys) |

## Body Parameters

At least one of `description` or `status` must be present, otherwise the request fails with `400`.

| Parameter     | Requirement | Type      | Description                              |
| ------------- | ----------- | --------- | ---------------------------------------- |
| `description` | Optional    | `string`  | A new description for the key            |
| `status`      | Optional    | `integer` | `1` to enable the key, `0` to disable it |

> **Note:** Disabling a key stops it authenticating immediately, and re-enabling restores it. The [API Keys](https://console.nebulablock.com/apiKeys) page in the console is the most reliable way to toggle a key. Keys cannot be regenerated in place — create a new key and delete the old one instead.

## Response Attributes

#### data `dict`

The updated key: `id`, `key`, `name`, `description`, `status`, and `created_at`.

#### status `string`

`success` or `failed`.

#### message `string`

A description of the result.

## Example

#### Request

```bash
curl -X PUT '{API_URL}/keys/5' \
-H 'Authorization: Bearer {TOKEN}' \
-H 'Content-Type: application/json' \
-d '{"description": "Key used by the production service"}'
```

## Known issues

Two problems in the current implementation make this endpoint unreliable. Prefer the console until they are resolved:

* **Disabling does not take effect.** `status: 0` is treated as absent, so the request is accepted but the key keeps authenticating. Only `status: 1` is acted on.
* **A successful update can still return `500`.** The update is committed, then the response is built from a value the service does not return, so the call fails after the change has already been written. Treat a `500` here as "possibly applied" and re-read the key with [List API Keys](/api-reference/platform-api/list-api-keys) rather than retrying blindly.

## See also

* [List API Keys](/api-reference/platform-api/list-api-keys)
* [Delete API Key](/api-reference/platform-api/list-api-keys/delete-api-key)


# Delete API Key

Permanently delete a Nebula Block API key. Applications using it stop authenticating immediately.

Permanently delete an API key. The key stops working immediately.

## HTTP Request

`DELETE` `{API_URL}/keys/{key_id}`

where `API_URL = https://api.nebulablock.com/api/v1`.

## Path Parameters

| Parameter | Requirement | Type      | Description                                                                        |
| --------- | ----------- | --------- | ---------------------------------------------------------------------------------- |
| `key_id`  | Required    | `integer` | The ID of the key, from [List API Keys](/api-reference/platform-api/list-api-keys) |

## Response Attributes

#### status `string`

`success` or `failed`.

#### message `string`

A description of the result.

## Example

#### Request

```bash
curl -X DELETE '{API_URL}/keys/5' \
-H 'Authorization: Bearer {TOKEN}'
```

#### Response

```json
{
    "data": [],
    "message": "API key deleted successfully",
    "status": "success"
}
```

> **Important:** Deleting a key cannot be undone. Any application still using it will start receiving authentication errors.

## See also

* [List API Keys](/api-reference/platform-api/list-api-keys)
* [Create API Key](/api-reference/platform-api/list-api-keys/create-api-key)
* [Update API Key](/api-reference/platform-api/list-api-keys/update-api-key)


# Object Storage

List your Nebula Block object storage workspaces, with status, charges, and pagination.

List the object storage workspaces on your account. A workspace is the container that holds your buckets and carries its own S3 access key pair.

## HTTP Request

`GET` `{API_URL}/object-storage/`

where `API_URL = https://api.nebulablock.com/api/v1`.

## Query Parameters

| Parameter      | Requirement | Type      | Description                                                                                                                                                         |
| -------------- | ----------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `space_status` | Required    | `string`  | Which workspaces to return. `Ready` returns active workspaces; **any other value** (the console sends `_Ready`) returns workspaces that are `Deleted` or `Disabled` |
| `page`         | Optional    | `integer` | Page number, starting at `1`. Defaults to `1`                                                                                                                       |
| `limit`        | Optional    | `integer` | Results per page, `1`–`100`. Defaults to `10`                                                                                                                       |
| `team_id`      | Optional    | `integer` | Act on a team's storage instead of your own. See [Teams](/account/teams)                                                                                            |

## Response Attributes

#### data `list`

The matching workspaces. Each entry contains:

* **object\_storage\_name** `string`: The workspace name, used as `object_storage_name` everywhere else.
* **status** `string`: `Ready`, `Deleted`, or `Disabled`.
* **active** `boolean`: Whether the workspace is currently active.
* **charges** `float`: Cumulative cost incurred by the workspace.
* **type** `integer`: The storage plan type. Defaults to `1`.
* **location** `string`: Where the workspace is hosted, lowercased — for example `canada`.
* **provider** `string`: Identifies the storage backend serving the workspace.
* **team** `object`: The owning team — `id`, `name`, `role`, `permission` — or `null` for a personal workspace.
* **user** `object`: The owning user — `id`, `name`, `email`.

#### meta `dict`

Pagination details: **total\_count**, **page**, **limit**, and **total\_pages**.

#### status `string`

`success` or `failed`.

#### message `string`

A description of the result.

## Example

#### Request

```bash
curl -X GET '{API_URL}/object-storage/?space_status=Ready&page=1&limit=10' \
-H 'Authorization: Bearer {TOKEN}'
```

#### Response

```json
{
    "data": [
        {
            "object_storage_name": "research-datasets",
            "charges": 1.2043,
            "active": true,
            "status": "Ready",
            "type": 1,
            "location": "canada",
            "team": null,
            "user": {"id": 18, "name": "Test User", "email": "testemail@gmail.com"}
        }
    ],
    "meta": {"total_count": 1, "page": 1, "limit": 10, "total_pages": 1},
    "message": "user object storage successfully retrieved",
    "status": "success"
}
```

## See also

* [Create Storage Workspace](/api-reference/platform-api/list-workspaces/create-workspace)
* [Object Storage](/products/object-storage)


# Create Storage Workspace

Provision a new object storage workspace and its S3 access key pair.

Provision a new object storage workspace. This also generates the workspace's S3 access key pair, though the keys are **not** returned here — read them from the console, or issue a fresh pair with [Regenerate Access Keys](/api-reference/platform-api/list-workspaces/regenerate-key-pair).

## HTTP Request

`POST` `{API_URL}/object-storage/`

where `API_URL = https://api.nebulablock.com/api/v1`.

## Body Parameters

| Parameter             | Requirement | Type      | Description                                                                                                                                                            |
| --------------------- | ----------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `object_storage_name` | Required    | `string`  | A name for the workspace. Must be unique among your workspaces                                                                                                         |
| `location`            | Optional    | `string`  | Where to provision the workspace — `Canada` or `US`. Defaults to Canada. Returned lowercased by [List Storage Workspaces](/api-reference/platform-api/list-workspaces) |
| `type`                | Optional    | `integer` | The storage tier. `1` is Standard, the free-storage tier. The console also offers Performance and Accelerated, which bill per GB per month and may be out of stock     |

## Response Attributes

#### data `list`

Always empty on this endpoint.

#### status `string`

`success` or `failed`.

#### message `string`

A description of the result. On failure this is what tells you why — the two you are most likely to see are `"Exceeded the create limit"` and `"The object storage name already exists. Please choose a different name."`

> **Note:** Business failures on this endpoint are returned as **HTTP 200 with `"status": "failed"`** and an explanatory `message`. Check `status`, not just the HTTP status code.

> **Note:** A workspace is usable immediately — it comes back `Ready` rather than going through a provisioning state.

Storage tiers and their rates are shown on the [create form](https://console.nebulablock.com/create-object-storage) in the console. At the time of writing Standard stores data free and bills only outgoing traffic per GB, with incoming traffic included.

## Example

#### Request

```bash
curl -X POST '{API_URL}/object-storage/' \
-H 'Authorization: Bearer {TOKEN}' \
-H 'Content-Type: application/json' \
-d '{"object_storage_name": "research-datasets"}'
```

#### Response

```json
{
    "data": [],
    "message": "Object storage successfully created",
    "status": "success"
}
```

## See also

* [List Storage Workspaces](/api-reference/platform-api/list-workspaces)
* [Regenerate Access Keys](/api-reference/platform-api/list-workspaces/regenerate-key-pair)
* [Object Storage Quickstart](/products/object-storage/quickstart)


# Delete Storage Workspace

Delete an object storage workspace and invalidate its access keys.

Delete an object storage workspace.

## HTTP Request

`DELETE` `{API_URL}/object-storage/`

where `API_URL = https://api.nebulablock.com/api/v1`.

## Query Parameters

| Parameter             | Requirement | Type      | Description                                                              |
| --------------------- | ----------- | --------- | ------------------------------------------------------------------------ |
| `object_storage_name` | Required    | `string`  | The workspace to delete                                                  |
| `team_id`             | Optional    | `integer` | Act on a team's storage instead of your own. See [Teams](/account/teams) |

## Response Attributes

#### data `list`

Always empty on this endpoint.

#### status `string`

`success` or `failed`.

#### message `string`

A description of the result.

> **Note:** Deleting a workspace that is already deleted succeeds rather than erroring, with the message `"storage <name> has been already deleted."` — so the call is safe to retry.

> **Important:** Deleting a workspace invalidates its access key pair. Anything still using those credentials will stop authenticating.

## Example

#### Request

```bash
curl -X DELETE '{API_URL}/object-storage/?object_storage_name=research-datasets' \
-H 'Authorization: Bearer {TOKEN}'
```

#### Response

```json
{
    "data": [],
    "message": "storage research-datasets has been deleted successfully.",
    "status": "success"
}
```

## See also

* [List Storage Workspaces](/api-reference/platform-api/list-workspaces)
* [Delete Bucket](/api-reference/platform-api/list-workspaces/delete-bucket)


# Regenerate Access Keys

Issue a new S3 access key pair for a workspace and invalidate the previous one.

Issue a new S3 access key pair for a workspace and invalidate the previous one. This is the only endpoint that returns the secret key, so capture it from the response.

## HTTP Request

`POST` `{API_URL}/object-storage/regenerate-key-pair`

where `API_URL = https://api.nebulablock.com/api/v1`.

## Body Parameters

| Parameter             | Requirement | Type     | Description                            |
| --------------------- | ----------- | -------- | -------------------------------------- |
| `object_storage_name` | Required    | `string` | The workspace whose keys to regenerate |

## Response Attributes

#### data `dict`

The new credentials:

* **new\_access\_key** `string`: The new access key.
* **new\_secret\_key** `string`: The new secret key.
* **message** `string`: Confirmation from the storage provider.

If the workspace name does not match one of yours, `data` is an empty list and `status` is `failed`.

#### status `string`

`success` or `failed`.

#### message `string`

A description of the result.

> **Important:** The old access key and secret are frozen and deleted as part of this call. Update your `s3cmd` config, SDK clients, and CI secrets before regenerating, not after.

## Example

#### Request

```bash
curl -X POST '{API_URL}/object-storage/regenerate-key-pair' \
-H 'Authorization: Bearer {TOKEN}' \
-H 'Content-Type: application/json' \
-d '{"object_storage_name": "research-datasets"}'
```

#### Response

```json
{
    "data": {
        "message": "New key pair created successfully.",
        "new_access_key": "...",
        "new_secret_key": "..."
    },
    "message": "user object storage AccessKey & SecretKey successfully regenerated",
    "status": "success"
}
```

## See also

* [Create Storage Workspace](/api-reference/platform-api/list-workspaces/create-workspace)
* [Object Storage Quickstart](/products/object-storage/quickstart)


# List Buckets

List the buckets in an object storage workspace with object counts, sizes, and privacy.

List every bucket in a workspace, with its object count, size, and privacy setting.

## HTTP Request

`GET` `{API_URL}/object-storage/buckets`

where `API_URL = https://api.nebulablock.com/api/v1`.

## Query Parameters

| Parameter             | Requirement | Type      | Description                                                              |
| --------------------- | ----------- | --------- | ------------------------------------------------------------------------ |
| `object_storage_name` | Required    | `string`  | The workspace to list buckets from                                       |
| `team_id`             | Optional    | `integer` | Act on a team's storage instead of your own. See [Teams](/account/teams) |

## Response Attributes

#### data `list`

The buckets in the workspace. Each entry contains:

* **id** `string`: The bucket's full name, including the `u-<hash>-<workspace>.` prefix the platform adds at creation. This is the name `s3cmd` and the S3 API see. Buckets predating the storage migration have no prefix.
* **file\_num** `integer`: Number of objects in the bucket. **`null`** for an empty bucket, not `0`.
* **storage\_size** `string`: Total size, already formatted for display (for example `"1.4 GB"`) rather than returned as a byte count.
* **create\_time** `string`: When the bucket was created, as an ISO 8601 UTC timestamp (`2026-08-07T18:52:29.362000+00:00`).
* **private** `integer`: `1` when the bucket is private, `0` when public, or `null` if the privacy setting could not be read.

#### status `string`

`success` or `failed`.

#### message `string`

A description of the result.

## Example

#### Request

```bash
curl -X GET '{API_URL}/object-storage/buckets?object_storage_name=research-datasets' \
-H 'Authorization: Bearer {TOKEN}'
```

#### Response

```json
{
    "data": [
        {
            "id": "u-2f36933d-research.checkpoints",
            "file_num": 128,
            "storage_size": "42.7 GB",
            "create_time": "2026-03-14T09:21:07.221000+00:00",
            "private": 1
        }
    ],
    "message": "buckets data successfully retrieved",
    "status": "success"
}
```

## See also

* [Create Bucket](/api-reference/platform-api/list-workspaces/create-bucket)
* [List Files](/api-reference/platform-api/list-workspaces/list-files)
* [Toggle Bucket Privacy](/api-reference/platform-api/list-workspaces/toggle-bucket-privacy)


# Create Bucket

Create a bucket inside a Nebula Block object storage workspace.

Create a bucket inside a workspace.

## HTTP Request

`POST` `{API_URL}/object-storage/bucket`

where `API_URL = https://api.nebulablock.com/api/v1`.

## Body Parameters

| Parameter             | Requirement | Type      | Description                                                                                                                           |
| --------------------- | ----------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `bucket_name`         | Required    | `string`  | The name of the bucket                                                                                                                |
| `object_storage_name` | Required    | `string`  | The workspace to create it in                                                                                                         |
| `region`              | Optional    | `string`  | The region to create the bucket in — `ca-central`. Safe to omit: the console does not send it and bucket creation succeeds without it |
| `team_id`             | Optional    | `integer` | Create under a team's storage. See [Teams](/account/teams)                                                                            |

> **Important:** The bucket is not created under the name you supply. The platform prefixes it, so `docs-verify` inside workspace `Personal0616-1` becomes `u-2f36933d-personal0616-1.docs-verify`. Read the resulting name from [List Buckets](/api-reference/platform-api/list-workspaces/list-buckets) — that `id` is what `s3cmd` and the S3 API see. Buckets created before the storage backend was migrated keep their original unprefixed names.

New buckets are **private** by default. See [Toggle Bucket Privacy](/api-reference/platform-api/list-workspaces/toggle-bucket-privacy).

## Response Attributes

#### data `dict`

The created bucket:

* **bucket\_name** `string`: The bucket's name.
* **region** `string`: The region it was created in.
* **domain** `string`: The domain the bucket is served from.
* **status** `string`: `success`.

On failure `data` is `null` and `message` carries the provider's error.

> **Note:** Business failures on this endpoint are returned as **HTTP 200 with `"status": "failed"`** and an explanatory `message`. Check `status`, not just the HTTP status code.

## Example

#### Request

```bash
curl -X POST '{API_URL}/object-storage/bucket' \
-H 'Authorization: Bearer {TOKEN}' \
-H 'Content-Type: application/json' \
-d '{"object_storage_name": "research-datasets", "bucket_name": "checkpoints"}'
```

#### Response

```json
{
    "data": {
        "status": "success",
        "bucket_name": "checkpoints",
        "region": "ca-central",
        "domain": "..."
    },
    "message": "Bucket 'checkpoints' was created successfully.",
    "status": "success"
}
```

## See also

* [List Buckets](/api-reference/platform-api/list-workspaces/list-buckets)
* [Delete Bucket](/api-reference/platform-api/list-workspaces/delete-bucket)
* [Upload File](/api-reference/platform-api/list-workspaces/upload-file)


# Delete Bucket

Delete a bucket from a Nebula Block object storage workspace.

Delete a bucket from a workspace.

## HTTP Request

`DELETE` `{API_URL}/object-storage/bucket`

where `API_URL = https://api.nebulablock.com/api/v1`.

## Query Parameters

| Parameter             | Requirement | Type      | Description                                                              |
| --------------------- | ----------- | --------- | ------------------------------------------------------------------------ |
| `object_storage_name` | Required    | `string`  | The workspace holding the bucket                                         |
| `bucket_name`         | Required    | `string`  | The bucket to delete                                                     |
| `team_id`             | Optional    | `integer` | Act on a team's storage instead of your own. See [Teams](/account/teams) |

## Response Attributes

#### data `list`

Always empty on this endpoint.

#### status `string`

`success` or `failed`.

#### message `string`

A description of the result.

> **Note:** Business failures on this endpoint are returned as **HTTP 200 with `"status": "failed"`** and an explanatory `message`. Check `status`, not just the HTTP status code.

## Example

#### Request

```bash
curl -X DELETE '{API_URL}/object-storage/bucket?object_storage_name=research-datasets&bucket_name=checkpoints' \
-H 'Authorization: Bearer {TOKEN}'
```

#### Response

```json
{
    "data": [],
    "message": "storage research-datasets has been deleted successfully.",
    "status": "success"
}
```

## See also

* [List Buckets](/api-reference/platform-api/list-workspaces/list-buckets)
* [Delete File](/api-reference/platform-api/list-workspaces/delete-file)


# List Files

List the objects in a bucket. Returns at most 1,000 entries and does not paginate.

List the objects in a bucket.

## HTTP Request

`GET` `{API_URL}/object-storage/bucket/files`

where `API_URL = https://api.nebulablock.com/api/v1`.

## Query Parameters

| Parameter             | Requirement | Type      | Description                                                              |
| --------------------- | ----------- | --------- | ------------------------------------------------------------------------ |
| `object_storage_name` | Required    | `string`  | The workspace holding the bucket                                         |
| `bucket_name`         | Required    | `string`  | The bucket to list                                                       |
| `team_id`             | Optional    | `integer` | Act on a team's storage instead of your own. See [Teams](/account/teams) |

## Response Attributes

#### data `list`

The objects in the bucket. Each entry contains:

* **key** `string`: The object key, including any path prefix. Pass this as `object_key` to [Get Download URL](/api-reference/platform-api/list-workspaces/get-download-url), or in `file_keys` to [Delete File](/api-reference/platform-api/list-workspaces/delete-file).
* **hash** `string`: The object's content hash.
* **fsize** `string`: The object's size, already formatted for display rather than a byte count.
* **mimeType** `string`: The object's MIME type. May be `null` when the type was not recorded.
* **putTime** `string`: When the object was stored, as an ISO 8601 UTC timestamp (`2026-08-13T01:19:49.081000+00:00`).

#### status `string`

`success` or `failed`.

#### message `string`

A description of the result.

> **Important:** A `bucket_name` that does not exist also returns `200` with `"status": "success"` and an empty `data` array — identical to a real but empty bucket. This endpoint cannot tell you whether a bucket exists, and a typo returns nothing rather than an error. Use [List Buckets](/api-reference/platform-api/list-workspaces/list-buckets) to confirm a bucket is really there.

> **Important:** This endpoint returns **at most 1,000 objects** and takes no pagination or prefix parameters. The response gives no indication that it truncated — a bucket reporting `file_num: 1733` in [List Buckets](/api-reference/platform-api/list-workspaces/list-buckets) still returns only 1,000 entries here. Do not use this endpoint to enumerate a bucket. For anything that must be complete, list through the S3 API with `s3cmd ls` or an AWS SDK paginator — see [Python SDK](/products/object-storage/sdk-python).

## Example

#### Request

```bash
curl -X GET '{API_URL}/object-storage/bucket/files?object_storage_name=research-datasets&bucket_name=checkpoints' \
-H 'Authorization: Bearer {TOKEN}'
```

#### Response

```json
{
    "data": [
        {
            "key": "run-42/model.safetensors",
            "hash": "Fh8xVqod2MQ1VZr1AtNjWnR3rTRP",
            "fsize": "2.1 GB",
            "mimeType": "application/octet-stream",
            "putTime": "2026-08-14T18:35:02.417000+00:00"
        }
    ],
    "message": "bucket files data successfully retrieved",
    "status": "success"
}
```

## See also

* [Upload File](/api-reference/platform-api/list-workspaces/upload-file)
* [Get Download URL](/api-reference/platform-api/list-workspaces/get-download-url)
* [Delete File](/api-reference/platform-api/list-workspaces/delete-file)


# Upload File

Upload a file into a bucket through the Platform API using multipart form data.

Upload a file into a bucket. This endpoint takes `multipart/form-data`, not JSON.

## HTTP Request

`POST` `{API_URL}/object-storage/upload`

where `API_URL = https://api.nebulablock.com/api/v1`.

## Form Parameters

| Parameter             | Requirement | Type      | Description                                                                               |
| --------------------- | ----------- | --------- | ----------------------------------------------------------------------------------------- |
| `object_storage_name` | Required    | `string`  | The workspace holding the bucket                                                          |
| `bucket_name`         | Required    | `string`  | The destination bucket                                                                    |
| `file`                | Required    | `file`    | The file to upload                                                                        |
| `path`                | Required    | `string`  | The key prefix to store the file under. Pass an empty string to upload to the bucket root |
| `team_id`             | Optional    | `integer` | Act on a team's storage. See [Teams](/account/teams)                                      |

The final object key is `path` joined to the uploaded file's own filename — uploading `model.safetensors` with `path=run-42` stores it as `run-42/model.safetensors`. Backslashes are normalised to `/`, and a `path` containing `..` is rejected as path traversal.

## Response Attributes

#### data `string`

The resulting object key. On failure the shape differs by cause: a rejected `path` (traversal) returns `null`, while a failed upload returns an empty list.

#### status `string`

`success` or `failed`.

#### message `string`

A description of the result.

> **Note:** Business failures on this endpoint are returned as **HTTP 200 with `"status": "failed"`** and an explanatory `message`. Check `status`, not just the HTTP status code.

> **Note:** This endpoint buffers the whole file through the platform API. For large files and bulk transfers, go straight to the S3 endpoint with `s3cmd` or an AWS SDK — see [s3cmd on Linux and macOS](/products/object-storage/s3cmd-linux-macos) and [Python SDK](/products/object-storage/sdk-python).

## Example

#### Request

```bash
curl -X POST '{API_URL}/object-storage/upload' \
-H 'Authorization: Bearer {TOKEN}' \
-F 'object_storage_name=research-datasets' \
-F 'bucket_name=checkpoints' \
-F 'path=run-42' \
-F 'file=@./model.safetensors'
```

#### Response

```json
{
    "data": "run-42/model.safetensors",
    "message": "File uploaded successfully",
    "status": "success"
}
```

## See also

* [List Files](/api-reference/platform-api/list-workspaces/list-files)
* [Get Download URL](/api-reference/platform-api/list-workspaces/get-download-url)
* [Delete File](/api-reference/platform-api/list-workspaces/delete-file)


# Get Download URL

Get a download URL for an object, pre-signed and expiring when the bucket is private.

Return a URL for downloading an object.

Whether the URL is signed depends on the **bucket's** privacy setting, not on anything you pass: a private bucket produces a pre-signed URL that expires, while a public bucket produces a plain URL and `expires` is ignored. See [Toggle Bucket Privacy](/api-reference/platform-api/list-workspaces/toggle-bucket-privacy).

## HTTP Request

`GET` `{API_URL}/object-storage/download-url`

where `API_URL = https://api.nebulablock.com/api/v1`.

## Query Parameters

| Parameter             | Requirement | Type      | Description                                                                     |
| --------------------- | ----------- | --------- | ------------------------------------------------------------------------------- |
| `object_storage_name` | Required    | `string`  | The workspace holding the bucket                                                |
| `bucket_name`         | Required    | `string`  | The bucket holding the object                                                   |
| `object_key`          | Required    | `string`  | The full object key, including any path prefix                                  |
| `expires`             | Optional    | `integer` | Lifetime of the signed URL in seconds. Defaults to `3600`. Private buckets only |
| `team_id`             | Optional    | `integer` | Act on a team's storage instead of your own. See [Teams](/account/teams)        |

## Response Attributes

#### data `dict`

* **download\_url** `string`: The URL to download the object from.

#### status `string`

`success` or `failed`.

#### message `string`

A description of the result.

## Example

#### Request

```bash
curl -X GET '{API_URL}/object-storage/download-url?object_storage_name=research-datasets&bucket_name=checkpoints&object_key=run-42/model.safetensors&expires=900' \
-H 'Authorization: Bearer {TOKEN}'
```

#### Response

```json
{
    "data": {"download_url": "https://..."},
    "message": "Download URL generated successfully",
    "status": "success"
}
```

## See also

* [List Files](/api-reference/platform-api/list-workspaces/list-files)
* [Toggle Bucket Privacy](/api-reference/platform-api/list-workspaces/toggle-bucket-privacy)


# Delete File

Delete one or more objects from a bucket in a single batched call.

Delete one or more objects from a bucket. Deletion is batched — pass every key you want removed in a single call.

## HTTP Request

`DELETE` `{API_URL}/object-storage/file`

where `API_URL = https://api.nebulablock.com/api/v1`.

## Body Parameters

| Parameter             | Requirement | Type      | Description                                                                                                    |
| --------------------- | ----------- | --------- | -------------------------------------------------------------------------------------------------------------- |
| `object_storage_name` | Required    | `string`  | The workspace holding the bucket                                                                               |
| `bucket_name`         | Required    | `string`  | The bucket holding the objects                                                                                 |
| `file_keys`           | Required    | `list`    | The object keys to delete, as returned by [List Files](/api-reference/platform-api/list-workspaces/list-files) |
| `team_id`             | Optional    | `integer` | Act on a team's storage. See [Teams](/account/teams)                                                           |

## Response Attributes

#### data `list`

Always empty on this endpoint.

#### status `string`

`success` or `failed`.

#### message `string`

A description of the result.

> **Note:** The response does not report per-key outcomes. To confirm what was removed, call [List Files](/api-reference/platform-api/list-workspaces/list-files) afterwards.

## Example

#### Request

```bash
curl -X DELETE '{API_URL}/object-storage/file' \
-H 'Authorization: Bearer {TOKEN}' \
-H 'Content-Type: application/json' \
-d '{
    "object_storage_name": "research-datasets",
    "bucket_name": "checkpoints",
    "file_keys": ["run-42/model.safetensors", "run-42/optimizer.pt"]
}'
```

#### Response

```json
{
    "data": [],
    "message": "File deleted successfully",
    "status": "success"
}
```

## See also

* [List Files](/api-reference/platform-api/list-workspaces/list-files)
* [Delete Bucket](/api-reference/platform-api/list-workspaces/delete-bucket)


# Toggle Bucket Privacy

Flip a bucket between public and private, which determines whether download URLs are signed.

Flip a bucket between public and private. This is a toggle, not a setter — it switches the bucket to whichever state it is not currently in, so read the current value from [List Buckets](/api-reference/platform-api/list-workspaces/list-buckets) first if you need a specific outcome.

Bucket privacy determines what [Get Download URL](/api-reference/platform-api/list-workspaces/get-download-url) hands back: private buckets produce expiring pre-signed URLs, public buckets produce plain ones.

## HTTP Request

`POST` `{API_URL}/object-storage/buckets/toggle-privacy`

where `API_URL = https://api.nebulablock.com/api/v1`.

## Body Parameters

| Parameter             | Requirement | Type      | Description                                          |
| --------------------- | ----------- | --------- | ---------------------------------------------------- |
| `object_storage_name` | Required    | `string`  | The workspace holding the bucket                     |
| `bucket_name`         | Required    | `string`  | The bucket to toggle                                 |
| `team_id`             | Optional    | `integer` | Act on a team's storage. See [Teams](/account/teams) |

## Response Attributes

#### data `dict`

The result of the toggle:

* **bucket\_name** `string`: The bucket that was toggled.
* **new\_private** `string`: The state the bucket is now in — `"1"` for private, `"0"` for public.
* **status\_code** `integer`: The provider's status code. Anything other than `200` means the toggle did not take effect.
* **error** `string`: The provider's error, or `null` on success.
* **ret** `object`: The provider's raw response.

#### status `string`

`success` or `failed`.

#### message `string`

A description of the result.

> **Note:** Business failures on this endpoint are returned as **HTTP 200 with `"status": "failed"`** and an explanatory `message`. Check `status`, not just the HTTP status code.

## Example

#### Request

```bash
curl -X POST '{API_URL}/object-storage/buckets/toggle-privacy' \
-H 'Authorization: Bearer {TOKEN}' \
-H 'Content-Type: application/json' \
-d '{"object_storage_name": "research-datasets", "bucket_name": "checkpoints"}'
```

#### Response

```json
{
    "data": {
        "bucket_name": "checkpoints",
        "new_private": "1",
        "status_code": 200,
        "error": null,
        "ret": {}
    },
    "message": "Bucket privacy toggled successfully",
    "status": "success"
}
```

> **Note:** Switching a bucket to private also triggers a CDN refresh, so a URL that was publicly reachable may take a moment to stop resolving.

## See also

* [List Buckets](/api-reference/platform-api/list-workspaces/list-buckets)
* [Get Download URL](/api-reference/platform-api/list-workspaces/get-download-url)


# Get Storage Usage

Read storage and transfer usage for a workspace over the last 24 hours, 7 days, and 30 days.

Return storage and transfer usage for a workspace, broken down over the last 24 hours, 7 days, and 30 days.

## HTTP Request

`GET` `{API_URL}/object-storage/usage-data`

where `API_URL = https://api.nebulablock.com/api/v1`.

## Query Parameters

| Parameter             | Requirement | Type      | Description                                                              |
| --------------------- | ----------- | --------- | ------------------------------------------------------------------------ |
| `object_storage_name` | Required    | `string`  | The workspace to report on                                               |
| `team_id`             | Optional    | `integer` | Act on a team's storage instead of your own. See [Teams](/account/teams) |

## Response Attributes

Unlike the other object storage endpoints, this one returns its payload directly rather than wrapping it in a `data` / `message` / `status` envelope.

#### storage\_name `string`

The workspace the report covers.

#### detail\_24h `list`

Hourly statistics for the last 24 hours. Each entry contains **hour** `string`, **traffic\_amount** `integer`, and **capacity\_amount** `integer`.

#### detail\_7d `list`

Daily statistics for the last 7 days. Each entry contains **date** `string`, **traffic\_amount** `integer`, and **capacity\_amount** `integer`.

#### detail\_30d `list`

Daily statistics for the last 30 days, in the same shape as `detail_7d`.

## Example

#### Request

```bash
curl -X GET '{API_URL}/object-storage/usage-data?object_storage_name=research-datasets' \
-H 'Authorization: Bearer {TOKEN}'
```

#### Response

```json
{
    "storage_name": "research-datasets",
    "detail_24h": [
        {"hour": "2026-08-24 11:00", "traffic_amount": 1048576, "capacity_amount": 45872349184}
    ],
    "detail_7d": [
        {"date": "2026-08-23", "traffic_amount": 20971520, "capacity_amount": 45872349184}
    ],
    "detail_30d": [
        {"date": "2026-08-01", "traffic_amount": 8388608, "capacity_amount": 41234567890}
    ]
}
```

## See also

* [Object Storage](/products/object-storage)
* [Billing](/api-reference/platform-api/get-credit-balance)


# Billing

Retrieve your current Nebula Block credit balance.

Retrieve the current credit balance for your account.

## HTTP Request

`GET` `{API_URL}/users/credits`

## Response Attributes

#### data `dict`

Returns the `data` object, containing the user credit balance in the field `available_balance`.

#### status `string`

Indicates the result of the request to get your credit balance. success signifies success, while failed indicates an error.

#### message `string`

A description of the status of the request.

## Example

#### Request

```bash
curl -X GET '{API_URL}/users/credits'
-H 'Authorization: Bearer {TOKEN/KEY}'
```

#### Response

```json
{
    "data": {
        "available_balance": "1228.55600"
    },
    "message": "User credit balance successfully retrieved",
    "status": "success"
}
```


# List Invoices

List the invoices generated for your Nebula Block credit purchases.

Retrieve a paginated list of your invoices, including details such as the invoice ID, price, invoiced time, and invoice type.

## HTTP Request

`GET` `{API_URL}/users/invoices?limit={limit}&offset={offset}`

| Parameters | Requirements | Type  | Description                                                                                         |
| ---------- | ------------ | ----- | --------------------------------------------------------------------------------------------------- |
| limit      | Optional     | `int` | The number of records to display per page                                                           |
| offset     | Optional     | `int` | The starting point for record retrieval (i.e., how many records to skip before starting to display) |

## Response Attributes

#### data `dict`

* **invoices**: List of user invoices objects.
* **total\_invoices**: total records count of user invoices.

> **Note:** When the account has no invoices at all, `data` is an empty **list** rather than an object with these keys, and `status` is still `success`. Handle both shapes.

#### status `string`

Indicates the result of the request. **success** signifies success, while **failed** indicates an error.

#### message `string`

A message confirming the successful retrieval of user invoices.

## Example

#### Request

```bash
curl -X GET '{API_URL}/users/invoices?limit=2&offset=0'
-H 'Authorization: Bearer {TOKEN/KEY}'
```

#### Response

```json
{
    "data": {
        "invoices": [
            {
                "invoiced_time": "EST 2024-10-29 14:19:32",
                "invoice_id": "#NB-20241029181932-266",
                "price": 229.95,
                "type": "Reload",
                "id": 3688,
                "user_id": 266
            },
            {
                "invoiced_time": "EST 2024-10-29 14:18:54",
                "invoice_id": "#NB-20241029181853-266",
                "price": 11.5,
                "type": "Reload",
                "id": 3687,
                "user_id": 266
            },
            {
                "invoiced_time": "EST 2024-10-29 14:15:29",
                "invoice_id": "#NB-20241029181528-266",
                "price": 114.98,
                "type": "Reload",
                "id": 3686,
                "user_id": 266
            }
        ],
        "total_invoices": 3
    },
    "message": "User invoices retrieved successfully",
    "status": "success"
}
```


# Download Invoice

Download a Nebula Block invoice by its ID.

Download a specific invoice by including the invoice\_id in the URL path. The `invoice_id` can be obtained from the response of the List\_Invoices endpoint, where it is returned as the `id` field.

## HTTP Request

`GET` `{API_URL}/users/invoice-download/{invoice_id}`

## Path Parameters

| Parameters  | Requirements | Type  | Description                                                                                                                          |
| ----------- | ------------ | ----- | ------------------------------------------------------------------------------------------------------------------------------------ |
| invoice\_id | Required     | `int` | The unique identifier of the invoice to download, from [List Invoices](/api-reference/platform-api/get-credit-balance/list-invoices) |

## Response

The invoice document itself, returned as a file download rather than the usual JSON envelope.

## Example

#### Request

```bash
curl -X GET '{API_URL}/users/invoice-download/{invoice_id}'
-H 'Authorization: Bearer {TOKEN/KEY}'
```

#### Response

The invoice PDF file will be downloaded automatically.


# Get Payment History

Retrieve the history of credit purchases and deductions on your account.

Retrieve your credit payment history for different products.

## HTTP Request

`GET` `{API_URL}/users/credits/history?limit={limit}&offset={offset}`

* `limit`: Specifies the number of records to display per page.
* `offset`: Specifies the starting point for record retrieval (i.e., how many records to skip before starting to display).

## Response Attributes

#### data `dict`

* **credit\_balance**: User available credit amount.
* **credit\_history**: List of credits hourly transaction history.
* **total\_credit\_histories**: Total history count.

#### status `string`

Indicates the result of the request. **success** signifies success, while **failed** indicates an error.

#### message `string`

A description of the status of the request.

## Example

#### Request

```bash
curl -X GET '{API_URL}/users/credits/history?limit=2&offset=0'
-H 'Authorization: Bearer {TOKEN/KEY}'
```

#### Response

```json
{
    "data": {
        "credit_balance": 9.8682,
        "credit_history": [
            {
                "user_id": 266,
                "computing_amount": 2.004,
                "serverless_amount": 0.0,
                "create_time": "EST 2024-10-10 06:54:58",
                "update_time": "EST 2024-10-10 07:54:58",
                "total": 2.004
            },
            {
                "user_id": 266,
                "computing_amount": 2.004,
                "serverless_amount": 0.0,
                "create_time": "EST 2024-10-10 05:54:58",
                "update_time": "EST 2024-10-10 06:54:58",
                "total": 2.004
            }
        ],
        "total_credit_histories": 2
    },
    "message": "User credit history successfully retrieved",
    "status": "success"
}
```


# FAQ

Answers to common questions about Nebula Block accounts, limits, billing, compute, and data residency.

## Getting started

**Can I use the platform for free?** You can create an account for free, but the free tier (Tier 1) has a per-model daily request cap of 0 on most of the catalog, so in practice you need credit to call models. A $5 deposit moves you to Tier 2 and opens things up. See [Tiers and Rate Limits](/account/tiers-and-limits).

**Which API do I call?** Two base URLs, one API key for both. Use `https://inference.nebulablock.com/v1` to run models, and `https://api.nebulablock.com/api/v1` to manage instances, storage, keys, and billing. See the [API Reference](/api-reference/api-reference).

**Can I use the OpenAI SDK?** Yes. The Inference API implements the OpenAI surface — set `base_url` to `https://inference.nebulablock.com/v1` and your Nebula Block key as `api_key`. See the [Quickstart](/getting-started/get-started/quickstart).

**How do I know which models are available?** Call [`GET /v1/models`](/api-reference/inference-api/list-models) for the live list, or browse the [Model Catalog](/products/serverless-inference/model-catalog).

## Limits and errors

**Why am I getting a `429`?** You have hit one of three limits: requests per minute, tokens per minute, or requests per day — either account-wide or for that specific model. The message says which. Per-day counters reset at 00:00 UTC. Your current limits are under [Limits](https://console.nebulablock.com/limits) in the console.

**A model works for someone else but returns `429` for me.** Daily caps are set per model *and* per tier, so the same model can be available at one tier and capped at zero on another. Upgrading your tier is what changes it.

**Why am I getting a `402`?** Your credit balance cannot cover the request. This is returned up front for priced jobs such as video generation, so nothing is queued or charged.

## Compute

**What do I need to rent a GPU?** Tier 3, reached with a $10 deposit, plus an SSH key on your account. See the [GPU Cloud Quickstart](/products/gpu-cloud/quickstart).

**What happens if I run out of credit while an instance is running?** Instances are deleted automatically when the balance is exhausted. Turn on Auto-Pay for anything you cannot afford to lose — see [Billing](/getting-started/get-started/billing).

**Am I billed for a stopped instance?** Yes. Instances are billed for as long as they exist, powered on or not. Terminate what you are done with.

## Data and accounts

**Where is my data processed?** Models marked 🇨🇦 in the [Model Catalog](/products/serverless-inference/model-catalog) are hosted in Canada, and GPU capacity is available in Canada, the US, Finland, France, and Norway. See [Sovereign AI Compute](https://www.nebulablock.com/ai-sovereign-compute) and the [Data Policy](/resources/legal/data-policy).

**Can I share resources with my team?** Yes — [Teams](/account/teams) give you shared billing, per-member roles, and team API keys. That is the supported route; the same payment card cannot be used on two separate accounts.

## 🌍 Nebula Block Supported Countries🌍

We provide the following list of countries and territories where **Nebula Block** services are officially supported. Accessing or attempting to access Nebula Block from outside these supported regions may result in service restrictions or account suspension.

### ✅ Supported Countries & Regions

* Albania
* Algeria
* Andorra
* Angola
* Antigua and Barbuda
* Argentina
* Armenia
* Australia
* Austria
* Bahamas
* Bahrain
* Bangladesh
* Barbados
* Belgium
* Belize
* Benin
* Bhutan
* Bolivia
* Bosnia and Herzegovina
* Botswana
* Brazil
* Brunei
* Bulgaria
* Burkina Faso
* Burundi
* Cabo Verde
* Cambodia
* Cameroon
* Canada
* Central African Republic
* Chad
* Chile
* Colombia
* Comoros
* Costa Rica
* Croatia
* Cyprus
* Czech Republic
* Denmark
* Dominica
* Dominican Republic
* Ecuador
* Egypt
* El Salvador
* Estonia
* Eswatini (Swaziland)
* Ethiopia
* Fiji
* Finland
* France
* Gabon
* Gambia
* Georgia
* Germany
* Ghana
* Greece
* Grenada
* Guatemala
* Guinea
* Guyana
* Haiti
* Honduras
* Hungary
* Iceland
* India
* Indonesia
* Ireland
* Israel
* Italy
* Jamaica
* Japan
* Jordan
* Kazakhstan
* Kenya
* Kuwait
* Laos
* Latvia
* Lebanon
* Lesotho
* Liberia
* Lithuania
* Luxembourg
* Madagascar
* Malawi
* Malaysia
* Maldives
* Malta
* Mauritania
* Mauritius
* Mexico
* Moldova
* Monaco
* Mongolia
* Montenegro
* Morocco
* Mozambique
* Namibia
* Nepal
* Netherlands
* New Zealand
* Nicaragua
* Niger
* Nigeria
* North Macedonia
* Norway
* Oman
* Pakistan
* Palestine
* Panama
* Papua New Guinea
* Paraguay
* Peru
* Philippines
* Poland
* Portugal
* Qatar
* Romania
* Rwanda
* Saint Kitts and Nevis
* Saint Lucia
* Saint Vincent and the Grenadines
* Samoa
* San Marino
* Saudi Arabia
* Senegal
* Serbia
* Seychelles
* Sierra Leone
* Singapore
* Slovakia
* Slovenia
* Solomon Islands
* Somalia
* South Africa
* South Korea
* Spain
* Sri Lanka
* Suriname
* Sweden
* Switzerland
* Taiwan
* Tanzania
* Thailand
* Togo
* Trinidad and Tobago
* Tunisia
* Turkey
* Uganda
* Ukraine
* United Arab Emirates
* United Kingdom
* United States
* Uruguay
* Uzbekistan
* Vietnam
* Zambia
* Zimbabwe

***

### 🔒 Access Disclaimer

Nebula Block services may be geo-restricted due to local regulations or infrastructure limitations. Attempting to use the service through VPNs, proxies, or other IP-masking techniques in unsupported regions is a violation of our Terms of Service.


# Glossary

Definitions of the terms used across the Nebula Block documentation.

**Inference API** The OpenAI-compatible API for running models — text, vision, image, video, embeddings, and reranking — at `https://inference.nebulablock.com/v1`.

**Platform API** The REST API for managing resources: instances, SSH keys, API keys, object storage, and billing, at `https://api.nebulablock.com/api/v1`.

**Serverless inference** Running a model on managed endpoints, with no servers to provision. Billed on usage.

**GPU instance** A virtual machine, container, or bare-metal server with GPUs attached, rented by the hour.

**Object storage** S3-compatible storage for unstructured data such as datasets, checkpoints, and model outputs.

**Workspace** The container for your object storage. A workspace holds buckets and carries its own S3 access key pair.

**Bucket** A named container for objects inside a storage workspace.

**SSH key** A cryptographic key pair used to log into instances securely. You upload the public half; the private half stays with you.

**API key** A long-lived credential, prefixed `sk-`, that authenticates requests to both APIs.

**Access token** A short-lived JWT issued at login. Suited to interactive sessions rather than applications.

**Tier** Your account level, from Tier 1 to Tier 4. It determines your rate limits, which products you can use, and how much credit you can hold. See [Tiers and Rate Limits](/account/tiers-and-limits).

**RPM / TPM / RPD** Requests per minute, tokens per minute, and requests per day — the three rate limits applied to inference calls. RPD counters reset at 00:00 UTC.

**Context length** The maximum number of tokens a model can consider in one request, prompt and response combined.

**Embedding** A dense numeric vector representing text, used for semantic search and retrieval.

**Reranking** Scoring retrieved documents against a query so the most relevant ones can be kept.

**Team** A shared workspace with its own members, roles, and API keys. See [Teams](/account/teams).

**Credit** The prepaid balance all usage is deducted from.

**Referral** A program that pays commission on the spend of users you refer.


# Contact Us

How to reach the Nebula Block team by email or through the support site.

To contact Nebula Block, you can either directly email us at <contact@nebulablock.com>, or visit our [contact page](https://www.nebulablock.com/support/contact-us).


# Legal

Nebula Block's legal documents: terms of service, privacy policy, data policy, and refund policy.

**Effective Date:** January 1, 2024 **Last Updated:** January 1, 2024

***

This section contains the legal documents governing your use of Nebula Block's platform and services. Please review each document carefully.

## Documents

* [Refund Policy](/resources/legal/refund-policy) — Credit refund eligibility and procedures
* [Privacy Policy](/resources/legal/privacy-policy) — How we handle your data
* [Data Policy](/resources/legal/data-policy) — Data processing, ownership, and protection
* [Terms of Service](/resources/legal/terms-of-service) — Platform terms and conditions

## Key Points

### Refund Policy

* Refund requests must be submitted within **24 hours** of purchase
* Only **unused credits** are eligible for refund
* Submit requests via HelpDesk or email at **<contact@nebulablock.com>**

### Privacy Policy

* We do **not sell** your personal information
* Industry-standard security measures protect your data
* You have the right to access, correct, or delete your personal information

### Data Policy

* You **retain all rights** to your data
* Customer data is logically isolated from other customers
* Data breach notifications are sent within **72 hours**

### Terms of Service

* You are responsible for maintaining account credential confidentiality
* All fees are quoted in **U.S. Dollars**
* Governed by the laws of the **Province of Quebec, Canada**

***

## Contact Information

For questions or concerns regarding any of these policies, please contact us:

**Nebula Block** HelpDesk: Submit a ticket through our HelpDesk Email: <contact@nebulablock.com>


# Terms of Service

The terms governing your use of Nebula Block services, including acceptable use and billing.

**Effective Date:** January 1, 2024 **Last Updated:** January 1, 2024

***

These Terms of Service ("Terms") govern your access to and use of Nebula Block's GPU cloud computing and inference platform, including all related APIs, tools, documentation, and services (collectively, the "Services").

## Acceptance of Terms

By creating an account or using the Services, you agree to be bound by these Terms. If you are using the Services on behalf of an organization, you represent that you have the authority to bind that organization to these Terms. If you do not agree, do not use the Services.

## Account Registration

You must provide accurate and complete information when creating an account. You are responsible for maintaining the confidentiality of your account credentials and for all activity that occurs under your account. You agree to notify Nebula Block immediately of any unauthorized use.

## Services Description

Nebula Block provides on-demand GPU cloud computing resources, inference API endpoints, and related infrastructure services. Specific service offerings, pricing, and resource specifications are detailed on our website and may be updated from time to time.

## Acceptable Use

You agree not to use the Services to: violate any applicable law or regulation; infringe upon the intellectual property rights of any third party; transmit malware, viruses, or any harmful code; engage in cryptocurrency mining unless explicitly authorized under your service plan; attempt to gain unauthorized access to any systems or networks connected to the Services; use the Services to develop or deploy any product or service that competes directly with Nebula Block; or engage in any activity that disrupts, degrades, or impairs the Services for other users.

## Payment and Billing

You agree to pay all fees associated with your use of the Services in accordance with the pricing and billing terms in effect at the time of purchase. All fees are quoted in U.S. Dollars unless otherwise stated. Nebula Block reserves the right to modify pricing. Failure to pay outstanding balances may result in suspension or termination of your account.

## Service Level and Availability

Nebula Block will use commercially reasonable efforts to maintain platform availability. Specific uptime commitments, if any, are set forth in a separate Service Level Agreement (SLA). Nebula Block is not liable for downtime caused by scheduled maintenance (with reasonable advance notice), factors beyond our reasonable control (force majeure), or your misuse of the Services.

## Intellectual Property

Nebula Block retains all rights in the platform, APIs, documentation, and underlying technology. These Terms do not grant you any rights to Nebula Block's trademarks, logos, or branding. You retain all rights to the content and data you create or upload through the Services, subject to the licenses granted herein.

## Limitation of Liability

To the maximum extent permitted by law, Nebula Block shall not be liable for any indirect, incidental, special, consequential, or punitive damages, including but not limited to loss of profits, data, or business opportunities, arising out of or related to your use of the Services. Nebula Block's total aggregate liability for any claims arising under these Terms shall not exceed the amount you paid to Nebula Block in the twelve (12) months preceding the event giving rise to the claim.

## Indemnification

You agree to indemnify and hold harmless Nebula Block, its officers, directors, employees, and agents from any claims, liabilities, damages, losses, or expenses (including reasonable attorney's fees) arising from your use of the Services, your violation of these Terms, or your infringement of any third-party rights.

## Termination

Either party may terminate the account at any time. Nebula Block may suspend or terminate your access to the Services immediately if you breach these Terms or engage in activity that threatens the security or integrity of the platform. Upon termination, your right to use the Services ceases immediately. Sections regarding intellectual property, limitation of liability, indemnification, and governing law survive termination.

## Modifications to Terms

Nebula Block reserves the right to modify these Terms at any time. We will notify you of material changes via email or through the platform at least thirty (30) days before they take effect. Your continued use of the Services after the effective date constitutes acceptance of the revised Terms.

## Governing Law

These Terms shall be governed by and construed in accordance with the laws of the Province of Quebec and the federal laws of Canada applicable therein, without regard to conflict of law principles. Any disputes arising under these Terms shall be resolved in the courts of competent jurisdiction in the Province of Quebec, Canada. Nebula Block is a corporation incorporated under the laws of the Province of Quebec, Canada.

## Entire Agreement

These Terms, together with the Refund Policy, Privacy Policy, and Data Policy, constitute the entire agreement between you and Nebula Block regarding the Services and supersede all prior agreements and understandings.


# Privacy Policy

How Nebula Block collects, uses, shares, and retains your personal information.

**Effective Date:** January 1, 2024 **Last Updated:** January 1, 2024

***

Nebula Block ("we," "us," or "our") is committed to protecting the privacy of our users ("you" or "your"). This Privacy Policy describes how we collect, use, disclose, and safeguard your information when you use our GPU cloud computing and inference services.

## Information We Collect

**Account Information.** When you register for an account, we collect your name, email address, billing address, and payment information (processed through a secure third-party payment processor).

**Usage Data.** We automatically collect data related to your use of our platform, including API call logs, compute session durations, resource utilization metrics, IP addresses, browser type, and access timestamps.

**User-Uploaded Content.** You may upload datasets, machine learning models, configuration files, or other content to our platform in connection with your use of our services. We collect and store this content as necessary to provide the services you have requested.

**Communications.** We retain records of correspondence when you contact our support team or otherwise communicate with us.

## How We Use Your Information

We use the information we collect to: provide, operate, and maintain our services; process transactions and send related notices; monitor and analyze usage patterns to improve platform performance and reliability; detect, prevent, and address fraud, abuse, and technical issues; communicate with you regarding account activity, updates, and promotional offers (with your consent where required); and comply with applicable legal obligations.

## Information Sharing and Disclosure

We do not sell your personal information. We may share information with third-party service providers who perform services on our behalf (e.g., payment processing, analytics, infrastructure hosting), in response to lawful requests by public authorities or as required by applicable law, in connection with a merger, acquisition, or sale of all or a portion of our assets, and with your consent or at your direction.

## Data Security

We implement industry-standard technical and organizational measures to protect your information against unauthorized access, alteration, disclosure, or destruction. These include encryption of data in transit and at rest, access controls, and regular security audits. However, no method of transmission or storage is completely secure, and we cannot guarantee absolute security.

## Data Retention

We retain your personal information for as long as your account is active or as needed to provide services. Upon account termination, we will delete or anonymize your data within ninety (90) days, except where retention is required by law or for legitimate business purposes (e.g., fraud prevention, dispute resolution).

## Your Rights

Depending on your jurisdiction, you may have the right to access, correct, or delete your personal information; object to or restrict certain processing activities; request data portability; and withdraw consent where processing is based on consent. To exercise any of these rights, submit a ticket through our HelpDesk or send an email to **<contact@nebulablock.com>**.

## Cookies and Tracking

Our platform uses cookies and similar tracking technologies to maintain session state, remember preferences, and analyze usage. You may control cookie settings through your browser, though disabling cookies may limit platform functionality.

## Children's Privacy

Our services are not directed to individuals under the age of 16. We do not knowingly collect personal information from children. If we become aware that we have collected information from a child, we will take steps to delete that information promptly.

## International Data Transfers

Your information may be transferred to and processed in countries other than your country of residence. We ensure appropriate safeguards are in place for such transfers in compliance with applicable data protection laws.


# Data Policy

How Nebula Block handles customer data: ownership, processing, isolation, deletion, and breach notification.

**Effective Date:** January 1, 2024 **Last Updated:** January 1, 2024

***

This Data Policy describes how Nebula Block handles, processes, and protects the data you store on or transmit through our platform.

## Data Ownership

You retain all rights, title, and interest in and to the data you upload, transmit, or generate through Nebula Block's services ("Your Data"). Nebula Block does not claim ownership of Your Data.

## License to Provide Services

By using our services, you grant Nebula Block a limited, non-exclusive license to access, process, and store Your Data solely as necessary to provide, maintain, and improve the services you have requested. We will not use Your Data for any other purpose without your explicit consent.

## Data Processing

Nebula Block processes Your Data on GPU infrastructure located in our data centers and partner facilities. Processing activities include executing compute workloads, running inference tasks, and storing intermediate and final outputs as directed by you. We do not access the content of Your Data except as necessary to provide the services, troubleshoot issues at your request, or comply with applicable law.

## Data Isolation

Each customer's data is logically isolated from other customers' data. We implement access controls, network segmentation, and encryption to prevent unauthorized cross-tenant access.

## Data Deletion

Upon your request or upon termination of your account, we will delete Your Data from our active systems within thirty (30) days. Residual copies in backup systems will be purged within ninety (90) days. Data that has been anonymized and aggregated for analytics purposes is not subject to deletion requests.

## Data Breach Notification

In the event of a data breach affecting Your Data, Nebula Block will notify affected users within seventy-two (72) hours of becoming aware of the breach, in accordance with applicable laws. Notification will include a description of the nature of the breach, the types of data affected, and the measures taken to address the incident.

## Subprocessors

Nebula Block may engage third-party subprocessors to assist in delivering our services (e.g., cloud infrastructure providers, monitoring tools). A current list of subprocessors is available upon request. We require all subprocessors to maintain data protection standards consistent with this Data Policy.

## Compliance

Nebula Block is committed to complying with applicable data protection regulations, including but not limited to Quebec's Act Respecting the Protection of Personal Information in the Private Sector (Law 25), the Personal Information Protection and Electronic Documents Act (PIPEDA), the General Data Protection Regulation (GDPR), and other relevant frameworks. We regularly review and update our practices to maintain compliance.


# Refund Policy

Nebula Block's refund eligibility rules and how to request a refund.

**Effective Date:** January 1, 2024 **Last Updated:** January 1, 2024

***

This Refund Policy governs all purchases made through Nebula Block's platform, including GPU compute credits, cloud infrastructure services, and inference API credits.

## Eligibility for Refund

Refund requests submitted **within twenty-four (24) hours** of the original purchase are eligible for a refund of **any unused credits**. Credits that have already been consumed (e.g., applied toward GPU compute time, inference requests, or other platform usage) during that period are non-refundable.

## No Refund After 24 Hours

Any refund request submitted **after twenty-four (24) hours** from the time of purchase will **not** be honored, regardless of whether credits remain unused. All sales become final once the 24-hour window has elapsed.

## How to Request a Refund

To request a refund, submit a ticket through our HelpDesk or send an email to **<contact@nebulablock.com>** within the eligible window. Please include your account email, transaction ID, and the date of purchase. Nebula Block will process eligible refund requests within five (5) to ten (10) business days.

## Exceptions

Nebula Block reserves the right to deny refund requests in cases of suspected fraud, abuse, or violation of these terms. Promotional credits, bonus credits, and free-tier allocations are not eligible for refund under any circumstances.


