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

# Upload and processing

> How SnapIt queues invoice extraction, shows pipeline status, and handles Needs Attention.

# Upload and processing

SnapIt accepts **PDF**, **JPG**, **JPEG**, and **PNG** files. The backend upload limit is configurable with `MAX_FILE_SIZE_MB` and defaults to **50 MB**. Uploads save the file and invoice row immediately; AI extraction runs in the background.

<Note>
  The OCR service has a separate **25 MB** limit by default (`OCR_MAX_UPLOAD_MB`) and processes up to **3 PDF pages** by default (`OCR_MAX_PDF_PAGES`). Keep files within the smaller OCR limit for predictable processing.
</Note>

## Upload from the app

<Steps>
  <Step title="Open Upload">
    Use **Workflow → Upload** in the sidebar.
  </Step>

  <Step title="Drop or select files">
    Drag-and-drop one or more invoices. Optionally associate a vendor so Tier 1 templates can apply.
  </Step>

  <Step title="Watch status">
    The invoice list polls while work is in flight. Credits are deducted when the upload is accepted.
  </Step>

  <Step title="Review">
    When status is **Ready**, open the invoice to correct fields, download **JSON**, or export.
  </Step>
</Steps>

<Note>
  Each successful upload costs credits (see [Credits and billing](/guides/credits)). If balance is too low, the API returns **402 Payment Required**.
</Note>

## File and OCR limits

* The app accepts `application/pdf`, `image/jpeg`, `image/jpg`, and `image/png`.
* `MAX_FILE_SIZE_MB` controls the backend upload check and defaults to 50 MB.
* `OCR_MAX_UPLOAD_MB` controls the OCR service check and defaults to 25 MB. A file between these limits may be accepted and stored first, then rejected by OCR with a file-too-large error.
* `OCR_MAX_PDF_PAGES` defaults to 3. Resource pressure can cause additional pages to be skipped according to the OCR service policy.
* OCR uses one in-flight job by default. When the service is busy or memory pressure is too high, it returns a temporary error and the background queue retries according to the deployment settings.
* If retries are exhausted or the result cannot be validated, the invoice appears as **Needs Attention**. This does not mean the original upload was lost; open the invoice to inspect its status and ask an administrator to reprocess it when appropriate.

OCR runs with PaddleOCR's Chinese + English model by default (`OCR_LANG=ch`). English-only (`en`) and Thai (`th`) models are supported by configuration. The current app documentation does not claim dedicated Malay OCR support.

For self-hosted deployments, PP-Structure table extraction is disabled by default because it requires substantially more memory. Limited crop refinement is enabled by default but may be skipped automatically when the OCR container is under memory pressure.

## Pipeline statuses

| `processingStatus` | UI label | Meaning |
| - | - | - |
| `queued` | Uploaded | File saved; waiting for a worker |
| `processing` | Processing | OCR / LLM extraction in progress |
| `completed` | Ready | Extraction finished; review or export |
| `needs_review` / `failed` | Needs Attention | Retries exhausted or validation failed |

```mermaid theme={null}
flowchart LR
  upload[Upload] --> queued[Uploaded]
  queued --> processing[Processing]
  processing --> ready[Ready]
  processing --> attention[Needs Attention]
```

## Needs Attention

Open **Workflow → Needs Attention** for invoices that failed extraction or need human review.

From invoice detail you can correct fields and save. Admins can also **reprocess** (optionally force a tier). After a successful reprocess, the invoice leaves the attention queue when status returns to **Ready**.

## Offline / PWA

SnapIt installs as a Progressive Web App:

* Previously opened list and detail pages can load offline.
* New uploads while offline are **queued on the device** and sync when you reconnect (or when the tab becomes visible again).
* Logout clears the offline upload queue so the next account cannot sync leftover files.

<Warning>
  Production PWAs require **HTTPS**. Large files need enough device storage; if storage is full, SnapIt shows a clear queue error instead of silently dropping the file.
</Warning>

## Programmatic upload

Integrations can upload with an API key instead of the UI:

* One-step: `POST /api/v1/invoices/upload`
* Two-step: `POST /api/v1/invoices/upload/init` then `POST /api/v1/invoices/upload/{invoiceId}/file`
* Balance: `GET /api/v1/credits/balance`
* Top-up: `GET /api/v1/credits/packages` → checkout → confirm

See [API overview](/api-reference/introduction) and the interactive endpoint pages. After a programmatic upload, poll `GET /api/v1/invoices/{id}` until `ready` is true, then read `data` for the extracted JSON. Credits and packages: [Credits and billing](/guides/credits).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.