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

# Quickstart

> Generate your first image with the Melius API in a few minutes.

## 1. Get an API key

In the Melius app, go to **Team settings → Integrations**, create a key, and copy it — it's shown once. See [Authentication](/api/authentication) for details.

## 2. Make your first request

Paste your key into the snippet below and run it. It creates a project and canvas, adds an image node with your prompt, runs it, waits for the generation to finish, and prints the URL of the generated image.

<CodeGroup>
  ```bash cURL theme={null}
  KEY="mel_..."
  BASE="https://api.melius.com/api/v1"
  AUTH=(-H "Authorization: Bearer $KEY" -H "Content-Type: application/json")

  PROJECT=$(curl -s "${AUTH[@]}" -d '{"title":"My first project"}' $BASE/projects | jq -r .id)
  CANVAS=$(curl -s "${AUTH[@]}" -d '{"title":"My first canvas"}' $BASE/projects/$PROJECT/canvases | jq -r .id)

  NODE=$(uuidgen | tr 'A-Z' 'a-z')
  curl -s "${AUTH[@]}" -d "{\"id\":\"$NODE\",\"nodeType\":\"image\",\"geometry\":{\"x\":0,\"y\":0,\"w\":380,\"h\":632},\"textPrompt\":\"a golden retriever puppy in a field\"}" $BASE/canvases/$CANVAS/direct/nodes > /dev/null

  RUN=$(curl -s "${AUTH[@]}" -d "{\"canvasId\":\"$CANVAS\"}" $BASE/nodes/$NODE/runs | jq -r .id)

  while true; do
    STATUS=$(curl -s "${AUTH[@]}" $BASE/node-runs/$RUN | jq -r .status)
    [ "$STATUS" = "finished" ] && break
    [ "$STATUS" = "failed" ] && { echo "generation failed"; exit 1; }
    sleep 2
  done

  curl -s "${AUTH[@]}" -d '{}' $BASE/node-runs/$RUN/download | jq -r .url
  ```

  ```python Python theme={null}
  import time, uuid, requests

  KEY = "mel_..."
  BASE = "https://api.melius.com/api/v1"
  auth = {"Authorization": f"Bearer {KEY}"}

  project = requests.post(f"{BASE}/projects", headers=auth, json={"title": "My first project"}).json()
  canvas = requests.post(f"{BASE}/projects/{project['id']}/canvases", headers=auth, json={"title": "My first canvas"}).json()

  node_id = str(uuid.uuid4())
  requests.post(f"{BASE}/canvases/{canvas['id']}/direct/nodes", headers=auth, json={
      "id": node_id,
      "nodeType": "image",
      "geometry": {"x": 0, "y": 0, "w": 380, "h": 632},
      "textPrompt": "a golden retriever puppy in a field",
  })

  run = requests.post(f"{BASE}/nodes/{node_id}/runs", headers=auth, json={"canvasId": canvas["id"]}).json()

  while True:
      status = requests.get(f"{BASE}/node-runs/{run['id']}", headers=auth).json()["status"]
      if status in ("finished", "failed"):
          break
      time.sleep(2)

  result = requests.post(f"{BASE}/node-runs/{run['id']}/download", headers=auth, json={}).json()
  print(result["url"])
  ```

  ```typescript TypeScript theme={null}
  const KEY = "mel_...";
  const BASE = "https://api.melius.com/api/v1";
  const headers = { Authorization: `Bearer ${KEY}`, "Content-Type": "application/json" };
  const post = <T>(path: string, body: unknown): Promise<T> =>
    fetch(`${BASE}${path}`, { method: "POST", headers, body: JSON.stringify(body) }).then((r) => r.json());
  const get = <T>(path: string): Promise<T> => fetch(`${BASE}${path}`, { headers }).then((r) => r.json());

  async function main() {
    const project = await post<{ id: string }>("/projects", { title: "My first project" });
    const canvas = await post<{ id: string }>(`/projects/${project.id}/canvases`, { title: "My first canvas" });

    const nodeId = crypto.randomUUID();
    await post(`/canvases/${canvas.id}/direct/nodes`, {
      id: nodeId,
      nodeType: "image",
      geometry: { x: 0, y: 0, w: 380, h: 632 },
      textPrompt: "a golden retriever puppy in a field",
    });

    const run = await post<{ id: string }>(`/nodes/${nodeId}/runs`, { canvasId: canvas.id });

    let status: string;
    do {
      await new Promise((r) => setTimeout(r, 2000));
      ({ status } = await get<{ status: string }>(`/node-runs/${run.id}`));
    } while (status !== "finished" && status !== "failed");

    const result = await post<{ url: string }>(`/node-runs/${run.id}/download`, {});
    console.log(result.url);
  }

  main();
  ```

  ```php PHP theme={null}
  <?php
  $KEY = "mel_...";
  $BASE = "https://api.melius.com/api/v1";

  function call($method, $path, $body = null) {
      global $KEY, $BASE;
      $ch = curl_init("$BASE$path");
      curl_setopt_array($ch, [
          CURLOPT_RETURNTRANSFER => true,
          CURLOPT_CUSTOMREQUEST => $method,
          CURLOPT_HTTPHEADER => ["Authorization: Bearer $KEY", "Content-Type: application/json"],
          CURLOPT_POSTFIELDS => $body === null ? null : json_encode($body),
      ]);
      return json_decode(curl_exec($ch), true);
  }

  function uuidv4() {
      $d = random_bytes(16);
      $d[6] = chr(ord($d[6]) & 0x0f | 0x40);
      $d[8] = chr(ord($d[8]) & 0x3f | 0x80);
      return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($d), 4));
  }

  $project = call("POST", "/projects", ["title" => "My first project"]);
  $canvas = call("POST", "/projects/{$project['id']}/canvases", ["title" => "My first canvas"]);

  $nodeId = uuidv4();
  call("POST", "/canvases/{$canvas['id']}/direct/nodes", [
      "id" => $nodeId,
      "nodeType" => "image",
      "geometry" => ["x" => 0, "y" => 0, "w" => 380, "h" => 632],
      "textPrompt" => "a golden retriever puppy in a field",
  ]);

  $run = call("POST", "/nodes/$nodeId/runs", ["canvasId" => $canvas["id"]]);

  do {
      sleep(2);
      $status = call("GET", "/node-runs/{$run['id']}")["status"];
  } while ($status !== "finished" && $status !== "failed");

  $result = call("POST", "/node-runs/{$run['id']}/download", new stdClass());
  echo $result["url"] . "\n";
  ```

  ```go Go theme={null}
  package main

  import (
  	"bytes"
  	"crypto/rand"
  	"encoding/json"
  	"fmt"
  	"io"
  	"net/http"
  	"time"
  )

  const key = "mel_..."
  const base = "https://api.melius.com/api/v1"

  func call(method, path string, body any) map[string]any {
  	var buf io.Reader
  	if body != nil {
  		b, _ := json.Marshal(body)
  		buf = bytes.NewReader(b)
  	}
  	req, _ := http.NewRequest(method, base+path, buf)
  	req.Header.Set("Authorization", "Bearer "+key)
  	req.Header.Set("Content-Type", "application/json")
  	resp, _ := http.DefaultClient.Do(req)
  	defer resp.Body.Close()
  	data, _ := io.ReadAll(resp.Body)
  	var out map[string]any
  	json.Unmarshal(data, &out)
  	return out
  }

  func uuidv4() string {
  	b := make([]byte, 16)
  	rand.Read(b)
  	b[6] = (b[6] & 0x0f) | 0x40
  	b[8] = (b[8] & 0x3f) | 0x80
  	return fmt.Sprintf("%x-%x-%x-%x-%x", b[0:4], b[4:6], b[6:8], b[8:10], b[10:16])
  }

  func main() {
  	project := call("POST", "/projects", map[string]any{"title": "My first project"})
  	canvas := call("POST", fmt.Sprintf("/projects/%s/canvases", project["id"]), map[string]any{"title": "My first canvas"})

  	nodeID := uuidv4()
  	call("POST", fmt.Sprintf("/canvases/%s/direct/nodes", canvas["id"]), map[string]any{
  		"id":         nodeID,
  		"nodeType":   "image",
  		"geometry":   map[string]any{"x": 0, "y": 0, "w": 380, "h": 632},
  		"textPrompt": "a golden retriever puppy in a field",
  	})

  	run := call("POST", fmt.Sprintf("/nodes/%s/runs", nodeID), map[string]any{"canvasId": canvas["id"]})

  	status := ""
  	for status != "finished" && status != "failed" {
  		time.Sleep(2 * time.Second)
  		status, _ = call("GET", fmt.Sprintf("/node-runs/%s", run["id"]), nil)["status"].(string)
  	}

  	result := call("POST", fmt.Sprintf("/node-runs/%s/download", run["id"]), map[string]any{})
  	fmt.Println(result["url"])
  }
  ```

  ```ruby Ruby theme={null}
  require "net/http"
  require "json"
  require "securerandom"

  KEY = "mel_..."
  BASE = "https://api.melius.com/api/v1"

  def call(method, path, body = nil)
    uri = URI("#{BASE}#{path}")
    req = (method == "GET" ? Net::HTTP::Get : Net::HTTP::Post).new(uri)
    req["Authorization"] = "Bearer #{KEY}"
    req["Content-Type"] = "application/json"
    req.body = body.to_json if body
    res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
    JSON.parse(res.body)
  end

  project = call("POST", "/projects", { title: "My first project" })
  canvas = call("POST", "/projects/#{project['id']}/canvases", { title: "My first canvas" })

  node_id = SecureRandom.uuid
  call("POST", "/canvases/#{canvas['id']}/direct/nodes", {
    id: node_id,
    nodeType: "image",
    geometry: { x: 0, y: 0, w: 380, h: 632 },
    textPrompt: "a golden retriever puppy in a field",
  })

  run = call("POST", "/nodes/#{node_id}/runs", { canvasId: canvas["id"] })

  status = nil
  until ["finished", "failed"].include?(status)
    sleep 2
    status = call("GET", "/node-runs/#{run['id']}")["status"]
  end

  result = call("POST", "/node-runs/#{run['id']}/download", {})
  puts result["url"]
  ```
</CodeGroup>

No model is specified, so Melius picks one for you. To choose a specific model, add a `modelConfig` to the node from [List generative models](/api/overview). The `x-team-id` header is optional — requests default to the team your key belongs to.

## Next steps

<Columns cols={2}>
  <Card title="Authentication" icon="key" href="/api/authentication">
    Keys, the `x-team-id` header, and how keys are scoped.
  </Card>

  <Card title="API overview" icon="book-open" href="/api/overview">
    The base URL, how generations work, rate limits, and credits.
  </Card>
</Columns>
