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

# Presigned URLs

> Parse documents from a URL instead of uploading them in the request body.

Instead of uploading a file with multipart form data, you can point `/parse` at a presigned URL using the `url` field. This is the right pattern when your documents already live in cloud storage (S3, GCS, Azure Blob, Supabase, etc.) — no need to download them locally first.

The submit-and-poll flow is identical to the upload path; only the request body differs.

<CodeGroup>
  ```python Python theme={null}
  import os
  import requests
  import time

  API_KEY = os.environ["UNSILOED_API_KEY"]
  BASE_URL = "https://prod.visionapi.unsiloed.ai"

  document_url = "https://example.com/path/to/your/document.pdf"

  response = requests.post(
      f"{BASE_URL}/parse",
      headers={"api-key": API_KEY},
      data={"url": document_url},
  )
  response.raise_for_status()

  job_id = response.json()["job_id"]
  print(f"Job submitted: {job_id}")

  while True:
      result = requests.get(
          f"{BASE_URL}/parse/{job_id}",
          headers={"api-key": API_KEY},
      ).json()
      print(f"Status: {result['status']}")
      if result["status"] == "Succeeded":
          break
      if result["status"] == "Failed":
          raise RuntimeError(result.get("message", "parse job failed"))
      time.sleep(5)

  print(f"Total chunks: {result['total_chunks']}")
  for chunk in result["chunks"]:
      print(chunk["embed"][:100])
  ```

  ```javascript JavaScript theme={null}
  const API_KEY = process.env.UNSILOED_API_KEY;
  const BASE_URL = "https://prod.visionapi.unsiloed.ai";

  const documentUrl = "https://example.com/path/to/your/document.pdf";

  const form = new FormData();
  form.append("url", documentUrl);

  const response = await fetch(`${BASE_URL}/parse`, {
    method: "POST",
    headers: { "api-key": API_KEY },
    body: form,
  });
  if (!response.ok) throw new Error(`${response.status}: ${await response.text()}`);

  const { job_id } = await response.json();
  console.log(`Job submitted: ${job_id}`);

  let result;
  while (true) {
    const res = await fetch(`${BASE_URL}/parse/${job_id}`, {
      headers: { "api-key": API_KEY },
    });
    result = await res.json();
    console.log(`Status: ${result.status}`);
    if (result.status === "Succeeded") break;
    if (result.status === "Failed") throw new Error(result.message || "parse job failed");
    await new Promise((r) => setTimeout(r, 5000));
  }

  console.log(`Total chunks: ${result.total_chunks}`);
  for (const chunk of result.chunks) {
    console.log(chunk.embed.slice(0, 100));
  }
  ```

  ```bash cURL theme={null}
  curl -X POST "https://prod.visionapi.unsiloed.ai/parse" \
    -H "api-key: $UNSILOED_API_KEY" \
    -F "url=https://example.com/path/to/your/document.pdf"

  # Then poll GET /parse/{job_id} until "status" is "Succeeded".
  ```
</CodeGroup>

<Note>
  For the full set of parameters accepted by `/parse`, see the [Parse API reference](/api-reference/parser/parse-document).
</Note>
