Skip to content

Batch outputs (download + parse JSONL)

Batch results are stored as files:

  • output_file_id: successful results
  • error_file_id: per-request errors

You can download these using GET /v1/files/{file_id}/content and parse them as JSONL.

Download

bash
curl https://api.fastapi.ai/v1/files/file-OUTPUT/content \
  -H "Authorization: Bearer $FAST_API_KEY" \
  --output output.jsonl
javascript
import fs from "node:fs";

const res = await fetch("https://api.fastapi.ai/v1/files/file-OUTPUT/content", {
  headers: { Authorization: `Bearer ${process.env.FAST_API_KEY}` },
});
if (!res.ok) throw new Error(`HTTP ${res.status}: ${await res.text()}`);

const buf = Buffer.from(await res.arrayBuffer());
fs.writeFileSync("output.jsonl", buf);
python
import os
import requests

resp = requests.get(
  "https://api.fastapi.ai/v1/files/file-OUTPUT/content",
  headers={"Authorization": f"Bearer {os.environ['FAST_API_KEY']}"},
)
resp.raise_for_status()

with open("output.jsonl", "wb") as f:
  f.write(resp.content)
go
package main

import (
  "io"
  "net/http"
  "os"
)

func main() {
  req, _ := http.NewRequest("GET", "https://api.fastapi.ai/v1/files/file-OUTPUT/content", nil)
  req.Header.Set("Authorization", "Bearer "+os.Getenv("FAST_API_KEY"))

  resp, err := http.DefaultClient.Do(req)
  if err != nil {
    panic(err)
  }
  defer resp.Body.Close()

  data, _ := io.ReadAll(resp.Body)
  _ = os.WriteFile("output.jsonl", data, 0o644)
}
java
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Files;
import java.nio.file.Path;

public class Main {
  public static void main(String[] args) throws Exception {
    HttpRequest req = HttpRequest.newBuilder()
      .uri(URI.create("https://api.fastapi.ai/v1/files/file-OUTPUT/content"))
      .header("Authorization", "Bearer " + System.getenv("FAST_API_KEY"))
      .GET()
      .build();

    HttpResponse<byte[]> resp = HttpClient.newHttpClient().send(req, HttpResponse.BodyHandlers.ofByteArray());
    Files.write(Path.of("output.jsonl"), resp.body());
  }
}

Parse JSONL

bash
curl https://api.fastapi.ai/v1/files/file-OUTPUT/content \
  -H "Authorization: Bearer $FAST_API_KEY" | \
  jq -r 'select(.custom_id) | "\(.custom_id) \(.response.status)"'
javascript
import fs from "node:fs";

const text = fs.readFileSync("output.jsonl", "utf-8");
for (const line of text.split("\n")) {
  if (!line.trim()) continue;
  const obj = JSON.parse(line);
  console.log(obj.custom_id, obj.response?.status);
}
python
import json

with open("output.jsonl", "r", encoding="utf-8") as f:
  for line in f:
    if not line.strip():
      continue
    obj = json.loads(line)
    print(obj.get("custom_id"), obj.get("response", {}).get("status"))
go
package main

import (
  "bufio"
  "encoding/json"
  "fmt"
  "os"
)

func main() {
  f, err := os.Open("output.jsonl")
  if err != nil {
    panic(err)
  }
  defer f.Close()

  scanner := bufio.NewScanner(f)
  for scanner.Scan() {
    line := scanner.Text()
    if line == "" {
      continue
    }
    var obj map[string]any
    if err := json.Unmarshal([]byte(line), &obj); err != nil {
      continue
    }
    resp, _ := obj["response"].(map[string]any)
    fmt.Println(obj["custom_id"], resp["status"])
  }
}
java
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.nio.file.Files;
import java.nio.file.Path;

public class Main {
  public static void main(String[] args) throws Exception {
    ObjectMapper mapper = new ObjectMapper();
    for (String line : Files.readAllLines(Path.of("output.jsonl"))) {
      if (line.trim().isEmpty()) continue;
      JsonNode obj = mapper.readTree(line);
      String customId = obj.path("custom_id").asText();
      String status = obj.path("response").path("status").asText();
      System.out.println(customId + " " + status);
    }
  }
}

那年我双手插兜, 让bug稳如老狗