> Documentation index: [/llms.txt](/llms.txt). Every page as one file: [/llms-full.txt](/llms-full.txt).

# Parse a file without indexing it

Parse a file without indexing it [#parse-a-file-without-indexing-it]

Extract text, tables, and document metadata from a file without adding it to search.

The response gives temporary URLs to the JSON output, or the parsed chunks inline.

Reference [#reference]

Flows [#flows]

| Flow  | Use for                                                     | Calls                                                                                                   |
| ----- | ----------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| Sync  | Files up to 25 MB (26,214,400 bytes), parsed in one request | `POST /parse/sync`                                                                                      |
| Async | Larger files or browser-based uploads                       | `POST /parse/initiate` → `PUT` bytes → `POST /parse/{file_id}/parse-only` → poll `GET /parse/{file_id}` |

On the sync flow a document over 500 pages is rejected; use the async flow.

Workspace [#workspace]

Parse calls are not scoped to a workspace.

| Call                   | Workspace handling                                                                                                                                     |
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Every parse call       | `X-Space-Slug` is not used, except that a workspace key must send its own workspace (`403` otherwise); a platform key or bearer token can leave it out |
| `POST /parse/sync`     | Optional form fields `space_slug` and `parent_id` are recorded on the file; `parent_id` must be an existing folder (`404` otherwise)                   |
| `POST /parse/initiate` | Takes no workspace; `parent_id` in the body must be an existing folder (`404` otherwise)                                                               |

Parsed output [#parsed-output]

```json
[
  {
    "text": "Extracted page or table text...",
    "metadata": {
      "page": 1,
      "type": "text"
    }
  }
]
```

| Call                                     | Returns                                                                                                                                   | Auth          |
| ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| `POST /parse/sync`                       | `{file_id, parsed_url, parsed_url_expires_in_seconds, page_count}`; always one `parsed_url`                                               | Key or bearer |
| `GET /parse/{file_id}`                   | `status`, `error`, `page_count`, and once `parsed`, either `parsed_url` or, for large PDFs, `parsed_urls`: one URL per part in page order | Key or bearer |
| `GET /parse/{file_id}/content?type=text` | `{file_id, type, chunks}`: the parsed chunks inline, only those whose `metadata.type` is `type` (`text`, the default, or `table`)         | Key or bearer |

`GET /parse/{file_id}/content` works once parsing is done (`parsed`, or `indexed` for a file from the regular upload flow); before that it returns `409`.

Statuses [#statuses]

| Status     | Meaning                                |
| ---------- | -------------------------------------- |
| `uploaded` | Uploaded.                              |
| `parsing`  | Extracting text and tables.            |
| `parsed`   | Parsed JSON is ready to download.      |
| `error`    | Parsing failed; see the `error` field. |

Errors [#errors]

| Status | `code`              | When                                                                                                                                    |
| ------ | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `400`  | `unsupported_mime`  | The file type is not supported; `details.allowed` lists the accepted MIME types                                                         |
| `400`  | `validation_error`  | Sync flow: the document has more than 500 pages                                                                                         |
| `404`  | `not_found`         | Unknown `file_id`, or the `parent_id` folder does not exist                                                                             |
| `409`  | `conflict`          | Kickoff on a file that is not `uploaded`, or kickoff or status for a file not created with `POST /parse/initiate` or `POST /parse/sync` |
| `413`  | `payload_too_large` | Sync flow: the file is over 25 MB                                                                                                       |
| `502`  | `parse_failed`      | The parser failed; `details.file_id` names the file                                                                                     |

Parse a small file [#parse-a-small-file]

1. To parse a file in one request, send it to `POST /parse/sync` as a multipart upload. `space_slug` and `parent_id` are optional form fields; see [Workspace](#workspace).

   ```python title="Python"
   import httpx

   FILES_URL = "https://alo-files-service-103105631559.europe-west8.run.app"
   HEADERS = {"X-API-Key": "sk-your-api-key"}

   with open("invoice.pdf", "rb") as f:
       parsed = httpx.post(
           f"{FILES_URL}/parse/sync",
           headers=HEADERS,
           files={"file": ("invoice.pdf", f, "application/pdf")},
           data={"space_slug": "acme", "parent_id": "root"},
       ).json()

   print(parsed["parsed_url"])
   ```

2. To get the parsed JSON, download `parsed_url` from the response. The URL expires after `parsed_url_expires_in_seconds`.

Parse a large file [#parse-a-large-file]

1. To start a parse upload, send `POST /parse/initiate` with the file name, MIME type, size, and target folder.

   ```python title="Python"
   upload = httpx.post(
       f"{FILES_URL}/parse/initiate",
       headers=HEADERS,
       json={
           "file_name": "deck.pptx",
           "mime_type": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
           "size_bytes": 9120000,
           "parent_id": "root",
       },
   ).json()
   ```

2. To send the file's bytes, `PUT` them to `upload["upload_url"]`, the same way as in a [regular upload](/docs/api/alo-files/uploads-and-folders). The request goes to storage, so it only needs the correct `Content-Type`.

3. To start parsing, send `POST /parse/{file_id}/parse-only`.

   ```python title="Python"
   httpx.post(f"{FILES_URL}/parse/{upload['file_id']}/parse-only", headers=HEADERS)
   ```

4. To get the output, poll `GET /parse/{file_id}` until `status` is `parsed`, then download `parsed_url`, or each of `parsed_urls` in page order. If `status` is `error`, see the `error` field.

   ```python title="Python"
   status = httpx.get(f"{FILES_URL}/parse/{upload['file_id']}", headers=HEADERS).json()

   if status["status"] == "parsed":
       print(status.get("parsed_url") or status.get("parsed_urls"))
   ```

Read parsed chunks inline [#read-parsed-chunks-inline]

1. To get the parsed chunks as JSON instead of downloading files, send `GET /parse/{file_id}/content` with `type` set to `text` or `table`.

   ```python title="Python"
   tables = httpx.get(
       f"{FILES_URL}/parse/{upload['file_id']}/content",
       headers=HEADERS,
       params={"type": "table"},
   ).json()

   for chunk in tables["chunks"]:
       print(chunk["metadata"], chunk["text"][:200])
   ```
