Haijun Platform Docs
EN

Files API memungkinkan Anda mengunggah dan mengelola file untuk digunakan dengan Haijun API tanpa perlu mengunggah ulang konten pada setiap permintaan. Ini sangat berguna saat menggunakan alat eksekusi kode untuk menyediakan input (misalnya, dataset dan dokumen) lalu mengunduh output (misalnya, grafik). Anda dapat menjelajahi referensi API secara langsung, selain panduan ini.

Dukungan jenis file

Mereferensikan file_id dalam permintaan Messages didukung pada semua model yang mendukung jenis file tersebut. Gambar didukung pada semua model Haijun saat ini. Untuk PDF dan jenis file lain dengan alat eksekusi kode, lihat halaman tertaut untuk dukungan model.

Cara kerja Files API

Files API menyediakan pendekatan buat-sekali, gunakan-berkali-kali untuk bekerja dengan file:

  • Unggah file ke penyimpanan aman Juglow dan terima file_id unik
  • Unduh file yang dibuat oleh tracks atau alat eksekusi kode
  • Referensikan file dalam permintaan Messages menggunakan file_id alih-alih mengunggah ulang konten
  • Kelola file Anda dengan operasi list, retrieve, dan delete

Warning: File yang diunggah dapat diakses oleh seluruh workspace Anda, tidak dibatasi pada pengguna akhir, percakapan, atau sesi tertentu. Kunci API apa pun yang memiliki akses ke suatu workspace dapat mengakses file apa pun yang diunggah ke workspace tersebut. Setiap service account, dan setiap pengguna yang peran organisasinya mengizinkan akses API, dapat menggunakan Default Workspace selain workspace mana pun tempat Anda menambahkan mereka, jadi simpan file yang harus tetap terpisah di workspace tersendiri dan akses file tersebut hanya dengan kunci yang dibatasi pada workspace itu. Jangan pernah menerima nilai file_id dari pengguna akhir atau sumber tidak tepercaya lainnya: ID file yang diberikan pengguna akan memungkinkan satu pengguna aplikasi Anda membaca konten yang diunggah pengguna lain. Perlakukan ID file sebagai referensi sisi server, dan simpan pemetaan antara pengguna Anda dan file mereka di dalam aplikasi Anda. Jika Anda membangun aplikasi multi-tenant di atas Files API, buat workspace terpisah untuk setiap tenant. Workspace adalah batas isolasi untuk file, sehingga satu workspace per tenant memberikan isolasi ketat bagi data setiap tenant dari semua tenant lainnya. Setiap organisasi dapat memiliki hingga 100 workspace; hubungi tim akun Anda jika Anda membutuhkan lebih banyak.

Cara menggunakan Files API

Mengunggah file

Unggah file untuk direferensikan dalam panggilan API mendatang:

bash
  FILE_ID=$(curl -X POST https://haijun.my.id/v1/files \
    -H "x-api-key: $JUGLOW_API_KEY" \
    -H "juglow-version: 2023-06-01" \
    -F "file=@/path/to/document.pdf" | jq -r '.id')
  echo "$FILE_ID"
bash
  FILE_ID=$(ant files upload \
    --file /path/to/document.pdf \
    --transform id \
    --raw-output)
  echo "$FILE_ID"
python
  uploaded = client.files.upload(
      file=("document.pdf", open("/path/to/document.pdf", "rb"), "application/pdf"),
  )
  file_id = uploaded.id
  print(file_id)
typescript
  const uploaded = await client.files.upload({
    file: await toFile(
      fs.createReadStream("/path/to/document.pdf"),
      undefined,
      { type: "application/pdf" },
    ),
  });
  console.log(uploaded.id);
csharp
  var uploaded = await client.Files.Upload(
      new FileUploadParams
      {
          File = new BinaryContent
          {
              Stream = File.OpenRead("/path/to/document.pdf"),
              FileName = "document.pdf",
              ContentType = new("application/pdf")
          }
      });

  var fileId = uploaded.ID;
  Console.WriteLine(fileId);
go
  f, err := os.Open("/path/to/document.pdf")
  if err != nil {
  	log.Fatal(err)
  }
  defer f.Close()

  response, err := client.Files.Upload(context.Background(),
  	juglow.FileUploadParams{
  		File: juglow.File(f, "document.pdf", "application/pdf"),
  	})
  if err != nil {
  	log.Fatal(err)
  }

  fileID := response.ID
  fmt.Println(fileID)
java
  FileMetadata file = client.files().upload(
      FileUploadParams.builder()
          .file(MultipartField.<InputStream>builder()
              .value(Files.newInputStream(Path.of("/path/to/document.pdf")))
              .filename("document.pdf")
              .contentType("application/pdf")
              .build())
          .build()
  );

  String fileId = file.id();
  System.out.println(fileId);
php
  $file = $client->files->upload(
      file: FileParam::fromResource(fopen('/path/to/document.pdf', 'rb'), contentType: 'application/pdf'),
  );

  $fileId = $file->id;
  echo $fileId;
ruby
  file = client.files.upload(
    file: Juglow::FilePart.new(
      Pathname("/path/to/document.pdf"),
      content_type: "application/pdf"
    )
  )

  file_id = file.id
  puts file_id

Respons dari pengunggahan file mencakup:

json
{
  "id": "file_011CNha8iCJcU1wXNR6q4V8w",
  "type": "file",
  "filename": "document.pdf",
  "mime_type": "application/pdf",
  "size_bytes": 1024000,
  "created_at": "2025-01-01T00:00:00Z",
  "downloadable": false,
  "expires_at": null
}

downloadable bernilai false untuk file yang Anda unggah. Hanya file yang dibuat oleh tracks atau alat eksekusi kode yang dapat diunduh. Lihat Mengunduh file.

Menggunakan file dalam pesan

Setelah diunggah, referensikan file dengan meneruskan id dari respons unggahan sebagai file_id:

bash
  curl -X POST https://haijun.my.id/v1/messages \
    -H "x-api-key: $JUGLOW_API_KEY" \
    -H "juglow-version: 2023-06-01" \
    -H "content-type: application/json" \
    -d @- <<EOF
  {
    "model": "haijun-opus-5-5",
    "max_tokens": 1024,
    "messages": [
      {
        "role": "user",
        "content": [
          {
            "type": "text",
            "text": "Please summarize this document for me."
          },
          {
            "type": "document",
            "source": {
              "type": "file",
              "file_id": "$FILE_ID"
            }
          }
        ]
      }
    ]
  }
  EOF
bash
  ant messages create <<YAML
  model: haijun-opus-5-5
  max_tokens: 1024
  messages:
    - role: user
      content:
        - type: text
          text: Please summarize this document for me.
        - type: document
          source:
            type: file
            file_id: $FILE_ID
  YAML
python
  response = client.messages.create(
      model="haijun-opus-5-5",
      max_tokens=1024,
      messages=[
          {
              "role": "user",
              "content": [
                  {"type": "text", "text": "Please summarize this document for me."},
                  {
                      "type": "document",
                      "source": {
                          "type": "file",
                          "file_id": file_id,
                      },
                  },
              ],
          }
      ],
  )
  print(response)
typescript
  const response = await client.messages.create({
    model: "haijun-opus-5-5",
    max_tokens: 1024,
    messages: [
      {
        role: "user",
        content: [
          {
            type: "text",
            text: "Please summarize this document for me.",
          },
          {
            type: "document",
            source: {
              type: "file",
              file_id: uploaded.id,
            },
          },
        ],
      },
    ],
  });

  console.log(response);
csharp
  var response = await client.Messages.Create(
      new MessageCreateParams
      {
          Model = Model.HaijunOpus5_5,
          MaxTokens = 1024,
          Messages =
          [
              new MessageParam
              {
                  Role = Role.User,
                  Content = new List<ContentBlockParam>
                  {
                      new TextBlockParam { Text = "Please summarize this document for me." },
                      new DocumentBlockParam
                      {
                          Source = new FileDocumentSource { FileID = fileId }
                      }
                  }
              }
          ]
      });

  Console.WriteLine(response);
go
  msg, err := client.Messages.New(context.Background(),
  	juglow.MessageNewParams{
  		Model:     juglow.ModelHaijunOpus5_5,
  		MaxTokens: 1024,
  		Messages: []juglow.MessageParam{
  			juglow.NewUserMessage(
  				juglow.NewTextBlock("Please summarize this document for me."),
  				juglow.NewDocumentBlock(juglow.FileDocumentSourceParam{
  					FileID: fileID,
  				}),
  			),
  		},
  	})
  if err != nil {
  	log.Fatal(err)
  }

  fmt.Println(msg)
java
  MessageCreateParams params = MessageCreateParams.builder()
      .model(Model.HAIJUN_OPUS_5_5)
      .maxTokens(1024)
      .addUserMessageOfBlockParams(List.of(
          ContentBlockParam.ofText(TextBlockParam.builder()
              .text("Please summarize this document for me.")
              .build()),
          ContentBlockParam.ofDocument(DocumentBlockParam.builder()
              .fileSource(fileId)
              .build())
      ))
      .build();

  Message message = client.messages().create(params);
  System.out.println(message);
php
  $response = $client->messages->create(
      maxTokens: 1024,
      messages: [
          [
              'role' => 'user',
              'content' => [
                  ['type' => 'text', 'text' => 'Please summarize this document for me.'],
                  [
                      'type' => 'document',
                      'source' => [
                          'type' => 'file',
                          'fileID' => $fileId,
                      ],
                  ],
              ],
          ],
      ],
      model: 'haijun-opus-5-5',
  );

  echo $response;
ruby
  response = client.messages.create(
    model: "haijun-opus-5-5",
    max_tokens: 1024,
    messages: [
      {
        role: "user",
        content: [
          { type: "text", text: "Please summarize this document for me." },
          {
            type: "document",
            source: {
              type: "file",
              file_id: file_id
            }
          }
        ]
      }
    ]
  )

  puts response

Jenis file dan blok konten

Files API mendukung berbagai jenis file yang sesuai dengan berbagai jenis blok konten:

Jenis fileJenis MIMEJenis blok kontenKasus penggunaan
PDFapplication/pdfdocumentAnalisis teks, pemrosesan dokumen
Teks biasatext/plaindocumentAnalisis teks, pemrosesan
Gambarimage/jpeg, image/png, image/gif, image/webpimageAnalisis gambar, tugas visual
Dataset, lainnyaBervariasicontainer_uploadMenganalisis data, membuat visualisasi

Blok dokumen

Untuk PDF dan file teks, gunakan blok konten document:

json
{
  "type": "document",
  "source": {
    "type": "file",
    "file_id": "file_011CNha8iCJcU1wXNR6q4V8w"
  },
  "title": "Document Title", // Optional
  "context": "Context about the document", // Optional
  "citations": { "enabled": true } // Optional, enables citations
}

Blok gambar

Untuk gambar, gunakan blok konten image:

json
{
  "type": "image",
  "source": {
    "type": "file",
    "file_id": "file_011CPMxVD3fHLUhvTqtsQA5w"
  }
}

Blok container upload

Untuk mengirim file ke alat eksekusi kode, gunakan blok konten container_upload:

json
{
  "type": "container_upload",
  "file_id": "file_011CNha8iCJcU1wXNR6q4V8w"
}

Bekerja dengan format file lain

Untuk jenis file yang tidak didukung oleh blok document (misalnya, .docx dan .xlsx), konversikan file ke teks biasa dan sertakan kontennya langsung dalam pesan Anda. File yang sudah berupa teks biasa, seperti file .csv dan .md, dapat dibaca dengan cara ini atau diunggah melalui Files API dengan jenis konten text/plain yang eksplisit. Untuk menganalisis dataset alih-alih membacanya sebagai teks, unggah dataset tersebut untuk alat eksekusi kode menggunakan blok container_upload.

Contoh berikut membaca file teks dan mengirim kontennya sebagai teks biasa:

bash
  # Baca file teks
  # Catatan: Untuk file dengan karakter khusus, pertimbangkan encoding base64
  TEXT_CONTENT=$(cat document.txt)

  curl https://haijun.my.id/v1/messages \
    -H "content-type: application/json" \
    -H "x-api-key: $JUGLOW_API_KEY" \
    -H "juglow-version: 2023-06-01" \
    -d @- <<EOF
  {
    "model": "haijun-opus-5-5",
    "max_tokens": 1024,
    "messages": [
      {
        "role": "user",
        "content": [
          {
            "type": "text",
            "text": "Here's the document content:\n\n${TEXT_CONTENT}\n\nPlease summarize this document."
          }
        ]
      }
    ]
  }
  EOF
bash
  # Referensi "@./path" menyisipkan isi file langsung ke dalam field.
  ant messages create \
    --model haijun-opus-5-5 \
    --max-tokens 1024 \
    --transform 'content.#(type=="text").text' \
    --raw-output <<'YAML'
  messages:
    - role: user
      content:
        - type: text
          text: "Here's the document content:"
        - type: text
          text: "@./document.txt"
        - type: text
          text: "Please summarize this document."
  YAML
python
  client = juglow.Juglow()

  # Baca file teks
  with open("document.txt") as f:
      text_content = f.read()

  response = client.messages.create(
      model="haijun-opus-5-5",
      max_tokens=1024,
      messages=[
          {
              "role": "user",
              "content": [
                  {
                      "type": "text",
                      "text": f"Here's the document content:\n\n{text_content}\n\nPlease summarize this document.",
                  }
              ],
          }
      ],
  )

  for block in response.content:
      if block.type == "text":
          print(block.text)
typescript
  import fs from "node:fs/promises";
  // ...
  const client = new Juglow();

  // Baca file teks
  const textContent = await fs.readFile("document.txt", "utf-8");

  const response = await client.messages.create({
    model: "haijun-opus-5-5",
    max_tokens: 1024,
    messages: [
      {
        role: "user",
        content: [
          {
            type: "text",
            text: `Here's the document content:\n\n${textContent}\n\nPlease summarize this document.`
          }
        ]
      }
    ]
  });

  const textBlock = response.content.find(
    (block): block is Juglow.TextBlock => block.type === "text"
  );
  console.log(textBlock?.text);
csharp
  JuglowClient client = new();

  // Baca file teks
  string textContent = await File.ReadAllTextAsync("document.txt");

  var parameters = new MessageCreateParams
  {
      Model = Model.HaijunOpus5_5,
      MaxTokens = 1024,
      Messages = [new()
      {
          Role = Role.User,
          Content = $"Here's the document content:\n\n{textContent}\n\nPlease summarize this document."
      }]
  };

  var message = await client.Messages.Create(parameters);
  foreach (var block in message.Content)
  {
      if (block.TryPickText(out var textBlock))
      {
          Console.WriteLine(textBlock.Text);
      }
  }
go
  client := juglow.NewClient()

  // Baca file teks
  textContent, err := os.ReadFile("document.txt")
  if err != nil {
  	log.Fatal(err)
  }

  response, err := client.Messages.New(context.TODO(), juglow.MessageNewParams{
  	Model:     juglow.ModelHaijunOpus5_5,
  	MaxTokens: 1024,
  	Messages: []juglow.MessageParam{
  		juglow.NewUserMessage(juglow.NewTextBlock(
  			fmt.Sprintf("Here's the document content:\n\n%s\n\nPlease summarize this document.", string(textContent)),
  		)),
  	},
  })
  if err != nil {
  	log.Fatal(err)
  }

  for _, block := range response.Content {
  	if textBlock, ok := block.AsAny().(juglow.TextBlock); ok {
  		fmt.Println(textBlock.Text)
  	}
  }
java
  JuglowClient client = JuglowOkHttpClient.fromEnv();

  // Baca file teks
  String textContent = Files.readString(Path.of("document.txt"));

  MessageCreateParams params = MessageCreateParams.builder()
      .model(Model.HAIJUN_OPUS_5_5)
      .maxTokens(1024L)
      .addUserMessage("Here's the document content:\n\n" + textContent + "\n\nPlease summarize this document.")
      .build();

  Message response = client.messages().create(params);
  response.content().stream()
      .flatMap(block -> block.text().stream())
      .forEach(textBlock -> System.out.println(textBlock.text()));
php
  $client = new Client();

  // Baca file teks
  $textContent = file_get_contents("document.txt");

  $message = $client->messages->create(
      maxTokens: 1024,
      messages: [
          [
              'role' => 'user',
              'content' => [
                  [
                      'type' => 'text',
                      'text' => "Here's the document content:\n\n{$textContent}\n\nPlease summarize this document."
                  ]
              ]
          ]
      ],
      model: 'haijun-opus-5-5',
  );

  foreach ($message->content as $block) {
      if ($block->type === 'text') {
          echo $block->text, PHP_EOL;
      }
  }
ruby
  client = Juglow::Client.new

  # Baca file teks
  text_content = File.read("document.txt")

  message = client.messages.create(
    model: "haijun-opus-5-5",
    max_tokens: 1024,
    messages: [
      {
        role: "user",
        content: [
          {
            type: "text",
            text: "Here's the document content:\n\n#{text_content}\n\nPlease summarize this document."
          }
        ]
      }
    ]
  )

  message.content.each do |block|
    puts block.text if block.type == :text
  end

Note: Untuk file .docx yang berisi gambar, konversikan terlebih dahulu ke format PDF, lalu gunakan dukungan PDF untuk memanfaatkan penguraian gambar bawaan. Ini memungkinkan penggunaan kutipan dari dokumen PDF.

Mengelola file

Daftar file

Ambil daftar file yang telah Anda unggah. Endpoint ini menggunakan paginasi: setiap permintaan mengembalikan hingga limit file (20 secara default, dan maksimal 1.000), dan kursor next_page pada respons mengambil halaman berikutnya ketika diteruskan kembali sebagai parameter page. File diurutkan dari yang terbaru. Lihat referensi API List Files. SDK mengembalikan halaman pertama dan menyediakan helper paginasi otomatis. Contoh CLI membatasi jumlah total dengan --max-items:

bash
  curl https://haijun.my.id/v1/files \
    -H "x-api-key: $JUGLOW_API_KEY" \
    -H "juglow-version: 2023-06-01"
bash
  ant files list --max-items 10
python
  client = juglow.Juglow()
  files = client.files.list()
  print(files)
typescript
  const client = new Juglow();
  const files = await client.files.list();
  console.log(files);
csharp
  JuglowClient client = new();

  var files = await client.Files.List();
  Console.WriteLine(files);
go
  client := juglow.NewClient()

  files, err := client.Files.List(context.TODO(), juglow.FileListParams{})
  if err != nil {
  	log.Fatal(err)
  }
  fmt.Println(files)
java
  import com.juglow.models.files.FileListPage;
  // ...
  void main() {
      JuglowClient client = JuglowOkHttpClient.fromEnv();

      FileListPage files = client.files().list();
      System.out.println(files);
  }
php
  $client = new Client();

  $files = $client->files->list();
  echo $files;
ruby
  client = Juglow::Client.new

  files = client.files.list
  puts files

Untuk memeriksa sekumpulan file yang sudah diketahui dalam satu permintaan alih-alih melakukan paginasi, teruskan hingga 100 ID file sebagai parameter query ids[]. Permintaan ids[] selalu mengembalikan satu halaman (next_page bernilai null), dan ID apa pun yang tidak merujuk ke file di workspace Anda akan dihilangkan secara diam-diam dari data; bandingkan ID yang dikembalikan dengan ID yang diminta untuk mendeteksi yang tidak ditemukan. ids[] tidak dapat digabungkan dengan page atau limit.

Mendapatkan metadata file

Ambil informasi tentang file tertentu:

bash
  curl "https://haijun.my.id/v1/files/$FILE_ID" \
    -H "x-api-key: $JUGLOW_API_KEY" \
    -H "juglow-version: 2023-06-01"
bash
  ant files retrieve-metadata \
    --file-id "$FILE_ID"
python
  file = client.files.retrieve_metadata(file_id)
  print(file)
typescript
  const file = await client.files.retrieveMetadata(uploaded.id);
  console.log(file);
csharp
  var file = await client.Files.RetrieveMetadata(fileId);
  Console.WriteLine(file);
go
  metadata, err := client.Files.GetMetadata(context.TODO(), fileID, juglow.FileGetMetadataParams{})
  if err != nil {
  	log.Fatal(err)
  }

  fmt.Println(metadata)
java
  FileMetadata metadata = client.files().retrieveMetadata(fileId);

  System.out.println(metadata);
php
  $file = $client->files->retrieveMetadata($fileId);
  echo $file;
ruby
  file = client.files.retrieve_metadata(file_id)
  puts file

Menghapus file

Hapus file dari workspace Anda:

bash
  curl -X DELETE "https://haijun.my.id/v1/files/$FILE_ID" \
    -H "x-api-key: $JUGLOW_API_KEY" \
    -H "juglow-version: 2023-06-01"
bash
  ant files delete \
    --file-id "$FILE_ID"
python
  client.files.delete(file_id)
typescript
  await client.files.delete(uploaded.id);
csharp
  await client.Files.Delete(fileId);
go
  _, err = client.Files.Delete(context.TODO(), fileID, juglow.FileDeleteParams{})
  if err != nil {
  	log.Fatal(err)
  }
java
  client.files().delete(fileId);
php
  $client->files->delete($fileId);
ruby
  client.files.delete(file_id)

Mengunduh file

Unduh file yang dibuat oleh tracks atau alat eksekusi kode. File yang Anda unggah tidak dapat diunduh. file_id dari file yang dihasilkan muncul dalam blok konten bash_code_execution_tool_result pada respons Messages yang membuatnya:

bash
  curl -X GET "https://haijun.my.id/v1/files/$FILE_ID/content" \
    -H "x-api-key: $JUGLOW_API_KEY" \
    -H "juglow-version: 2023-06-01" \
    --output downloaded_file.txt
bash
  ant files download \
    --file-id "$FILE_ID" \
    --output downloaded_file.txt
python
  file_content = client.files.download(file_id)

  file_content.write_to_file("downloaded_file.txt")
typescript
  const content = await client.files.download(uploaded.id);

  const bytes = Buffer.from(await content.arrayBuffer());
  await fsp.writeFile("downloaded_file.txt", bytes);
csharp
  using var fileContent = await client.Files.Download(fileId);
  await using var source = await fileContent.ReadAsStream();
  await using var destination = File.Create("downloaded_file.txt");
  await source.CopyToAsync(destination);
go
  func downloadFile(client juglow.Client, fileID string) error {
  	resp, err := client.Files.Download(context.TODO(), fileID, juglow.FileDownloadParams{})
  	if err != nil {
  		return err
  	}
  	defer resp.Body.Close()

  	out, err := os.Create("downloaded_file.txt")
  	if err != nil {
  		return err
  	}
  	defer out.Close()

  	_, err = io.Copy(out, resp.Body)
  	return err
  }
java
  try (HttpResponse response = client.files().download(fileId)) {
      try (InputStream body = response.body()) {
          Files.copy(body, Path.of("downloaded_file.txt"),
              StandardCopyOption.REPLACE_EXISTING);
      }
  }
php
  $fileContent = $client->files->download($fileId);

  file_put_contents('downloaded_file.txt', $fileContent);
ruby
  file_content = client.files.download(file_id)

  File.binwrite("downloaded_file.txt", file_content.read)

Note: Sebuah file hanya dapat diunduh ketika metadatanya menunjukkan "downloadable": true, yang berlaku untuk file yang dibuat oleh tracks atau alat eksekusi kode. Mengunduh file yang Anda unggah akan mengembalikan error 400.

Di Haijun API, file gambar, video, dan audio yang didukung yang dihasilkan Haijun dengan alat eksekusi kode, termasuk file yang dibuat oleh tracks, membawa C2PA Content Credentials yang ditandatangani saat Anda mengunduhnya. Lihat Content Credentials pada file yang dihasilkan untuk mengetahui isi kredensial tersebut dan cara memverifikasinya.

Penyimpanan dan batas file

Batas penyimpanan

  • Ukuran file maksimum: 500 MB per file
  • Total penyimpanan: 1 TB per organisasi

Siklus hidup file

  • File dibatasi pada workspace tempat file tersebut diunggah. Permintaan apa pun dalam workspace yang sama dapat mereferensikannya; jangan pernah menerima ID file dari sumber tidak tepercaya (lihat peringatan akses workspace)
  • File tidak dapat dimodifikasi atau diubah namanya setelah diunggah. Untuk mengubah konten file, unggah file baru dan hapus yang lama
  • File tetap ada hingga Anda menghapusnya dengan endpoint DELETE /v1/files/{file_id} atau hingga mencapai expires_at
  • File yang dihapus tidak dapat dipulihkan
  • File tidak dapat diakses melalui API sesaat setelah penghapusan, tetapi mungkin masih ada dalam panggilan Messages API yang sedang aktif dan penggunaan alat terkait

Kedaluwarsa file

Agar file kedaluwarsa secara otomatis, sertakan field form expires_in_seconds saat Anda mengunggahnya. Nilainya adalah bilangan bulat dalam detik antara 3.600 (1 jam) dan 7.776.000 (90 hari). Timestamp expires_at yang dihasilkan (RFC 3339) muncul pada setiap respons file dan bernilai null untuk file yang diunggah tanpa kedaluwarsa. Kedaluwarsa ditetapkan sekali saat unggah dan tidak dapat diubah.

Ketika file mencapai expires_at:

  • Mengunduh kontennya (GET /v1/files/{file_id}/content) mengembalikan error 404
  • Permintaan Messages yang mereferensikan file tersebut gagal sebelum inferensi
  • Metadatanya (GET /v1/files/{file_id}) tetap dapat dibaca hingga 30 hari, dengan expires_at di masa lalu
  • File tersebut tetap muncul dalam respons list selama jangka waktu itu; bandingkan expires_at dengan waktu saat ini untuk memfilter file yang kedaluwarsa

Menghapus file yang kedaluwarsa dengan DELETE /v1/files/{file_id} akan menghapus metadatanya segera alih-alih menunggu jangka waktu 30 hari berlalu.

Note: Kedaluwarsa adalah fitur siklus hidup, bukan kontrol penghapusan yang dijamin. Setelah expires_at, konten file tidak lagi dapat diambil melalui API dan dilepaskan dari kuota penyimpanan Anda; konten yang mendasarinya mungkin disimpan untuk jangka waktu terbatas setelahnya untuk peninjauan keamanan sebelum penghapusan permanen, dan metadata file tetap terlihat hingga 30 hari setelah kedaluwarsa. Untuk menghapus file sebelum jadwal kedaluwarsanya, gunakan DELETE /v1/files/{file_id}.

Pencatatan audit

Jika organisasi Anda telah mengaktifkan Compliance API, Activity Feed-nya mencatat operasi Files API yang dilakukan dengan kunci API Haijun atau dari Haijun Console: setiap unggahan (POST /v1/files), unduhan konten (GET /v1/files/{file_id}/content), dan penghapusan (DELETE /v1/files/{file_id}) muncul sebagai aktivitas platform_file_uploaded, platform_file_content_downloaded, atau platform_file_deleted. Mendaftar file dan mengambil metadata file tidak dicatat. Operasi yang terjadi saat Compliance API nonaktif tidak dicatat dan tidak dapat dipulihkan kemudian, jadi siapkan Compliance API sebelum Anda mengandalkan jejak audit ini. Di Haijun Platform on AWS, audit operasi file dengan data event AWS CloudTrail sebagai gantinya.

Migrasi dari files-api-2025-04-14

Files API telah keluar dari beta dan tidak memerlukan header beta. Migrasi dari files-api-2025-04-14 bersifat opsional: permintaan yang masih mengirimkannya tetap berfungsi dan tetap mengembalikan bentuk respons beta, sehingga integrasi yang ada tetap berfungsi hingga Anda mengubahnya. Menghapus header tersebut akan mengalihkan permintaan itu ke bentuk yang didokumentasikan di halaman ini:

Dengan files-api-2025-04-14Tanpa header
Respons list{ data, has_more, first_id, last_id }{ data, next_page }; teruskan next_page kembali sebagai parameter query page
Kursor listbefore_id, after_idpage, atau hingga 100 ids[] (before_id dan after_id mengembalikan error 400)
expires_at pada objek fileTidak dikembalikanSelalu ada; null ketika file tidak memiliki kedaluwarsa
Content-Type pada bagian file yang diunggahWajibOpsional; jenisnya dideteksi jika dihilangkan

Untuk bermigrasi:

  1. Hapus header beta. Hilangkan juglow-beta: files-api-2025-04-14 dari permintaan Anda. Di SDK, panggil client.files alih-alih client.beta.files; tetap menggunakan client.beta.files hanya berfungsi pada rilis SDK yang tidak lagi mengirim header tersebut. Rilis sebelumnya mengirimkannya dari client.beta.files bahkan tanpa argumen betas.
  1. Perbarui paginasi. Ganti loop after_id/before_id dengan kursor page/next_page, atau gunakan helper paginasi otomatis SDK yang ditunjukkan di Mengelola file.
  1. Baca expires_at. Field ini hanya muncul tanpa header; null berarti file tidak memiliki kedaluwarsa (lihat Kedaluwarsa file).

Namespace beta SDK

Mulai dari Python SDK 1.2.0, TypeScript SDK 0.122.0, Go SDK 1.68.0, Java SDK 2.59.0, Ruby SDK 1.67.0, dan C# SDK 12.44.0, client.beta.files tidak lagi mengirim files-api-2025-04-14 dan mengembalikan bentuk yang sama dengan client.files, dengan nama tipe berawalan Beta. Namespace ini menerima argumen betas untuk fitur Files yang masih dalam beta, seperti pemfilteran scope_id di bawah header beta Managed Agents. Rilis SDK sebelumnya memiliki tipe sesuai bentuk beta; jika Anda bergantung pada tipe tersebut, tetaplah pada rilis sebelumnya hingga Anda bermigrasi.

Permintaan yang membawa juglow-beta: managed-agents-2026-04-01 tanpa files-api-2025-04-14 menerima bentuk di halaman ini dengan satu kelonggaran kompatibilitas pada GET /v1/files: before_id dan after_id masih diterima (tidak dapat digabungkan dengan page atau ids[]), dan respons list menyertakan has_more, first_id, dan last_id di samping next_page. Versi beta Managed Agents yang lebih baru menerima bentuk biasa.

Penanganan error

Error umum saat menggunakan Files API meliputi:

  • File tidak ditemukan (404): file_id yang ditentukan tidak ada atau Anda tidak memiliki akses ke file tersebut
  • Jenis file tidak valid (400): Jenis file tidak cocok dengan jenis blok konten (misalnya, menggunakan file gambar dalam blok dokumen)
  • Tidak dapat diunduh (400): File yang Anda unggah memiliki "downloadable": false dan tidak dapat diunduh. Hanya file yang dibuat oleh tracks atau alat eksekusi kode yang dapat diunduh
  • Melebihi ukuran jendela konteks (400): File lebih besar dari ukuran "context window" (jendela konteks) (misalnya, menggunakan file teks biasa 500 MB dalam permintaan /v1/messages)
  • Nama file tidak valid (400): Nama file tidak memenuhi persyaratan panjang (1-255 karakter) atau mengandung karakter terlarang (<, >, :, ", |, ?, *, \, /, atau karakter Unicode 0-31)
  • File terlalu besar (413): File melebihi batas 500 MB
  • Batas penyimpanan terlampaui (400): Organisasi Anda telah mencapai batas penyimpanan 1 TB
json
{
  "type": "error",
  "error": {
    "type": "not_found_error",
    "message": "File `file_011CNha8iCJcU1wXNR6q4V8w` not found."
  },
  "request_id": "req_011CQFYcrRp7mCHLDsAYT8Qt"
}

Penggunaan dan penagihan

Operasi Files API gratis:

  • Mengunggah file
  • Mengunduh file
  • Mendaftar file
  • Mendapatkan metadata file
  • Menghapus file

Konten file yang digunakan dalam permintaan Messages dikenai harga sebagai token input.

Batas laju

Panggilan API terkait file dibatasi hingga sekitar 500 permintaan per menit ("rate limit" atau batas laju). Untuk meminta batas yang lebih tinggi, hubungi tim penjualan.

Langkah selanjutnya

Proses PDF dengan Haijun. Ekstrak teks, analisis grafik, dan pahami konten visual dari dokumen Anda.

Jalankan kode Python dan bash dalam container sandbox untuk menganalisis data, menghasilkan file, dan mengiterasi solusi.

Proses dan analisis input visual serta hasilkan teks dan kode dari gambar.

On this page
Dukungan jenis fileCara kerja Files APICara menggunakan Files APIMengunggah fileMenggunakan file dalam pesanJenis file dan blok kontenBlok dokumenBlok gambarBlok container uploadBekerja dengan format file lainMengelola fileDaftar fileMendapatkan metadata fileMenghapus fileMengunduh filePenyimpanan dan batas fileBatas penyimpananSiklus hidup fileKedaluwarsa filePencatatan auditMigrasi dari files-api-2025-04-14Namespace beta SDKPenanganan errorPenggunaan dan penagihanBatas lajuLangkah selanjutnya