Lunos logoLunos

Multimodal PDF

Lunos mendukung input berupa file PDF melalui endpoint POST /v1/chat/completions dengan format pesan yang kompatibel.

File PDF dapat dikirim melalui dua cara:

  • URL publik — cukup sertakan tautan langsung ke file PDF.
  • Data URL Base64 — gunakan format data:application/pdf;base64,... untuk file lokal atau privat.

Endpoint

POST /v1/chat/completions

Autentikasi

Authorization: Bearer YOUR_SECRET_KEY
Content-Type: application/json

Struktur Konten File

{
  "type": "file",
  "file": {
    "filename": "document.pdf",
    "file_data": "https://example.com/document.pdf"
  }
}

Lunos menerima beberapa variasi nama properti seperti file_data, fileData, dan url. Sistem akan secara otomatis menormalisasi payload sebelum meneruskannya ke penyedia model.

Konfigurasi Plugin (Opsional)

Anda dapat menggunakan parameter plugins untuk memilih engine parser yang ingin digunakan:

{
  "plugins": [
    {
      "id": "file-parser",
      "pdf": {
        "engine": "cloudflare-ai"
      }
    }
  ]
}

Pilihan engine yang tersedia:

  • cloudflare-ai
  • mistral-ocr
  • native

Biaya Pemrosesan PDF

Biaya untuk memproses PDF dapat terdiri dari beberapa komponen:

  • Penggunaan token oleh model AI.
  • Biaya pemrosesan parser dokumen.
  • Biaya tambahan proses OCR untuk dokumen hasil pindaian (scan).

Perlu diketahui bahwa PDF hasil scan biasanya memakan biaya yang lebih tinggi dibandingkan PDF berbasis teks karena memerlukan proses OCR tambahan.

Contoh Menggunakan URL PDF

cURL

curl -X POST "https://api.lunos.tech/v1/chat/completions" \
  -H "Authorization: Bearer YOUR_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "google/gemini-2.5-pro",
    "messages": [
      {
        "role": "user",
        "content": [
          { "type": "text", "text": "Apa saja poin utama yang dibahas dalam dokumen ini?" },
          {
            "type": "file",
            "file": {
              "filename": "bitcoin.pdf",
              "file_data": "https://bitcoin.org/bitcoin.pdf"
            }
          }
        ]
      }
    ],
    "plugins": [
      {
        "id": "file-parser",
        "pdf": { "engine": "mistral-ocr" }
      }
    ]
  }'

Python

import requests

payload = {
    "model": "google/gemini-2.5-pro",
    "messages": [
        {
            "role": "user",
            "content": [
                {"type": "text", "text": "Apa saja poin utama yang dibahas dalam dokumen ini?"},
                {
                    "type": "file",
                    "file": {
                        "filename": "bitcoin.pdf",
                        "file_data": "https://bitcoin.org/bitcoin.pdf",
                    },
                },
            ],
        }
    ],
    "plugins": [
        {"id": "file-parser", "pdf": {"engine": "mistral-ocr"}}
    ],
}
response = requests.post(
    "https://api.lunos.tech/v1/chat/completions",
    headers={
        "Authorization": "Bearer YOUR_SECRET_KEY",
        "Content-Type": "application/json",
    },
    json=payload,
)
print(response.json())
const response = await fetch("https://api.lunos.tech/v1/chat/completions", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_SECRET_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    model: "google/gemini-2.5-pro",
    messages: [
      {
        role: "user",
        content: [
          { type: "text", text: "Apa saja poin utama yang dibahas dalam dokumen ini?" },
          {
            type: "file",
            file: {
              filename: "bitcoin.pdf",
              file_data: "https://bitcoin.org/bitcoin.pdf",
            },
          },
        ],
      },
    ],
    plugins: [{ id: "file-parser", pdf: { engine: "mistral-ocr" } }],
  }),
});
console.log(await response.json());

Contoh Menggunakan Base64 PDF

cURL

curl -X POST "https://api.lunos.tech/v1/chat/completions" \
  -H "Authorization: Bearer YOUR_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "google/gemma-3-27b-it",
    "messages": [
      {
        "role": "user",
        "content": [
          { "type": "text", "text": "Tolong buatkan ringkasan dari dokumen ini." },
          {
            "type": "file",
            "file": {
              "filename": "document.pdf",
              "file_data": "data:application/pdf;base64,PASTE_BASE64_HERE"
            }
          }
        ]
      }
    ]
  }'
import base64
import requests

with open("document.pdf", "rb") as f:
    b64 = base64.b64encode(f.read()).decode("utf-8")

payload = {
    "model": "google/gemma-3-27b-it",
    "messages": [
        {
            "role": "user",
            "content": [
                {"type": "text", "text": "Tolong buatkan ringkasan dari dokumen ini."},
                {
                    "type": "file",
                    "file": {
                        "filename": "document.pdf",
                        "file_data": f"data:application/pdf;base64,{b64}",
                    },
                },
            ],
        }
    ],
}
response = requests.post(
    "https://api.lunos.tech/v1/chat/completions",
    headers={
        "Authorization": "Bearer YOUR_SECRET_KEY",
        "Content-Type": "application/json",
    },
    json=payload,
)
print(response.json())

TypeScript

import fs from "node:fs/promises";

const pdf = await fs.readFile("document.pdf");
const b64 = pdf.toString("base64");

const response = await fetch("https://api.lunos.tech/v1/chat/completions", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_SECRET_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    model: "google/gemma-3-27b-it",
    messages: [
      {
        role: "user",
        content: [
          { type: "text", text: "Tolong buatkan ringkasan dari dokumen ini." },
          {
            type: "file",
            file: {
              filename: "document.pdf",
              file_data: `data:application/pdf;base64,${b64}`,
            },
          },
        ],
      },
    ],
  }),
});
console.log(await response.json());

Menggunakan Ulang Annotations untuk Menghemat Biaya Parsing

Pada beberapa response, Lunos akan menyertakan data annotations yang berisi hasil parsing file di dalam choices[].message.annotations. Data annotation ini dapat Anda gunakan kembali di turn (giliran percakapan) selanjutnya sehingga Anda tidak perlu memproses ulang file yang sama — menghemat waktu dan biaya parsing secara signifikan.

Skema Annotation (Ringkas)

{
  "type": "file",
  "file": {
    "hash": "abc123...",
    "name": "document.pdf",
    "content": [
      { "type": "text", "text": "Parsed text..." },
      { "type": "image_url", "image_url": { "url": "data:image/png;base64,..." } }
    ]
  }
}

Contoh Format Response

{
  "choices": [
    {
      "message": {
        "role": "assistant",
        "content": "Dokumen membahas...",
        "annotations": [
          {
            "type": "file",
            "file": {
              "hash": "abc123...",
              "name": "document.pdf",
              "content": [{ "type": "text", "text": "Parsed text..." }]
            }
          }
        ]
      }
    }
  ],
  "usage": {
    "prompt_tokens": 1000,
    "completion_tokens": 100,
    "total_tokens": 1100
  }
}

Panduan Penanganan Masalah (Troubleshooting)

Hasil Ekstraksi Teks Kurang Akurat

  • Coba gunakan engine OCR (misalnya mistral-ocr) untuk dokumen yang merupakan hasil pindaian (scan).
  • Pastikan kualitas hasil scan cukup baik dan teks dapat terbaca dengan jelas.
  • Untuk PDF berukuran sangat besar, pertimbangkan untuk memecahnya menjadi beberapa bagian terlebih dahulu.

Ukuran Payload Terlalu Besar

  • Sebisa mungkin gunakan tautan URL dibandingkan mengirim data Base64.
  • Kirimkan hanya halaman-halaman yang relevan dengan pertanyaan Anda, bukan keseluruhan dokumen.

Checklist Panduan Lunos

  • Gunakan POST /v1/chat/completions dengan tipe konten type: "file".
  • Gunakan tautan URL untuk PDF yang bisa diakses publik atau berukuran besar; gunakan Base64 untuk file privat atau lokal.
  • Konfigurasi parameter plugins hanya jika Anda membutuhkan perilaku parser yang spesifik.
  • Manfaatkan data annotations dari response sebelumnya untuk percakapan multi-turn pada dokumen yang sama agar lebih efisien.