roasOS

Getting started

Make a key, quote an image, run it, and read the result.

This page is one complete flow. It makes a still image with Nano Banana Pro. The image costs 2 credits at the default resolution.

Every paid action in roasOS uses the same four steps: key, quote, run, poll. The steps hold on both entry paths. Read the flow as REST calls from your own code, or as instructions to an AI agent.

1. Make a key

Make an API key in your workspace settings. A key starts with roasos_sk_. You need a Growth plan or a Scale plan.

Keep the key on your server. Send it as a bearer token.

export ROASOS_API_KEY="roasos_sk_..."

Test the key:

curl https://api.roasos.com/v1/account \
  -H "Authorization: Bearer $ROASOS_API_KEY"

The response gives your workspace, your plan and your credit balance. Refer to Authentication.

The same key opens the REST API and the MCP server. You need no second credential.

2. Quote, run, poll

Quote the image

Send the request with quote_only: true. roasOS calculates the price and spends nothing.

Each paid request also needs an Idempotency-Key header. The value is your own unique text of 16 to 255 characters. Use the same value for the quote and for the run.

curl -X POST https://api.roasos.com/v1/image/nano-banana-pro \
  -H "Authorization: Bearer $ROASOS_API_KEY" \
  -H "Idempotency-Key: my-first-image-0001" \
  -H "Content-Type: application/json" \
  -d '{
    "quote_only": true,
    "prompt": "A red sneaker on a white background, studio product photo, soft top light."
  }'

The response gives the price and a quote_id:

{
  "data": {
    "kind": "quote",
    "quote_id": "7f3c1a52-9b04-4e6d-8a71-2c5f0d9e4b13",
    "credits": 2,
    "expires_at": "2026-08-22T10:14:11Z",
    "confirmation": { "model": "nano-banana-pro", "example": "1_image_1K" }
  }
}

A quote is valid for 10 minutes.

Run the image

Send the same body and the same Idempotency-Key. Put the quote_id in place of quote_only.

This step uses your credits.

curl -X POST https://api.roasos.com/v1/image/nano-banana-pro \
  -H "Authorization: Bearer $ROASOS_API_KEY" \
  -H "Idempotency-Key: my-first-image-0001" \
  -H "Content-Type: application/json" \
  -d '{
    "quote_id": "7f3c1a52-9b04-4e6d-8a71-2c5f0d9e4b13",
    "prompt": "A red sneaker on a white background, studio product photo, soft top light."
  }'

The response is a job:

{
  "data": {
    "id": "3d9b6c40-51ae-4f28-9c37-8e0a4b71d562",
    "kind": "image",
    "model": "nano-banana-pro",
    "status": "queued",
    "credits_reserved": 2,
    "links": {
      "status": "/v1/jobs/3d9b6c40-51ae-4f28-9c37-8e0a4b71d562/status",
      "result": "/v1/jobs/3d9b6c40-51ae-4f28-9c37-8e0a4b71d562/result"
    }
  }
}

Poll, then read the result

Poll the status every few seconds:

curl https://api.roasos.com/v1/jobs/3d9b6c40-51ae-4f28-9c37-8e0a4b71d562/status \
  -H "Authorization: Bearer $ROASOS_API_KEY"
{ "data": { "id": "3d9b6c40-51ae-4f28-9c37-8e0a4b71d562", "status": "processing", "updated_at": "..." } }

When the status is completed, read the result:

curl https://api.roasos.com/v1/jobs/3d9b6c40-51ae-4f28-9c37-8e0a4b71d562/result \
  -H "Authorization: Bearer $ROASOS_API_KEY"
{
  "data": {
    "id": "3d9b6c40-51ae-4f28-9c37-8e0a4b71d562",
    "kind": "image",
    "model": "nano-banana-pro",
    "status": "completed",
    "result": {
      "images": ["https://cdn.roasos.com/workspaces/ws_01/images-1.png"]
    }
  }
}

GET /v1/jobs/{id}/result gives 409 run_not_completed until the job is terminal. Poll the status endpoint first. Refer to Jobs.

The result file is immutable. Send its URL as the media input of your next request. One example is the first frame of a video.

Next steps

On this page