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

# Working with files

> How Zapier passes files to Nitro PDF Services actions, how to chain actions, and the input formats each action expects.

Every Nitro action takes a file and returns either a file or structured data. Zapier's file
handling makes both ends easier than they are in most integrations, with a few things worth
knowing.

## Getting files in

Zapier represents a file either as a file object or as a URL. The Nitro app accepts both: if a
step hands it a URL, the app downloads the file first and then uploads it to Nitro. You do not
need a separate download step.

| Source | Field to map into the Nitro step |
| - | - |
| Google Drive, Dropbox, Box, OneDrive | The trigger's or search step's file field |
| Gmail / Outlook / Email by Zapier | The attachment field |
| Webhooks by Zapier | A URL in the payload, mapped straight into the file field |
| Formatter, Files by Zapier | The produced file object |
| A previous Nitro action | Its file output, such as **Compressed PDF File** |

<Note>
  Only the file's bytes reach Nitro — its name is not passed through. Set the name on the step that
  writes the result instead.
</Note>

## Getting results out

### Files

With **Output Type** set to *Download file*, the action returns a file object under a labelled
field such as **Compressed PDF File** or **Merged PDF File**. Map that field into any
file-accepting input: a Drive upload, a Dropbox upload, a Gmail attachment, or the file input of
another Nitro action.

### URLs and metadata

With *Download URL*, the action returns:

| Field | Description |
| - | - |
| `file_url` | Download URL for the output |
| `content_type` | MIME type of the output |
| `file_size_bytes` | Size in bytes |
| `page_count` | Pages in the output |

Use this when you want the metadata — for example, to record how much a compression saved, or to
branch on page count — or when the destination app takes a URL rather than a file.

<Warning>
  Output URLs are valid for about 15 minutes; Nitro then deletes the file. Consume the URL in the
  same Zap run rather than storing it in a database or sheet.
</Warning>

## Chaining actions

Nitro actions chain by mapping one step's file output into the next step's file input. With
*Download file* on each step, a scan-to-archive Zap looks like:

<Steps>
  <Step title="Ocr PDF">
    **PDF File** → the trigger's file. **Language** → the document's language.
  </Step>

  <Step title="Optimize PDF">
    **PDF File** → **OCR PDF File** from step 1. **Optimization Profile** → *Archive*.
  </Step>

  <Step title="PDF to PDF/A">
    **PDF File** → **Optimized PDF File** from step 2. Leave the conformance level at *2b*.
  </Step>

  <Step title="Google Drive — Upload File">
    **File** → **PDF/A File** from step 3.
  </Step>
</Steps>

Two pairs of actions are designed to chain through their structured outputs:

<AccordionGroup>
  <Accordion title="Smart PII Detection or Text Bounding Box Extract → Redact PDF">
    Both extraction actions emit a **Redactions JSON** field shaped exactly like **Redact PDF**'s
    **Redactions JSON** input. Map it straight across:

    1. **Smart PII Detection** — **PDF File** → the source document.
    2. **Redact PDF** — **PDF File** → the same source document; **Redactions JSON** → step 1's
       **Redactions JSON**.
    3. Upload **Redacted PDF File** wherever the original is not.

    To redact only some matches, use **Filter by Zapier** on `pii_types[]` or route the
    `redactions[]` line items through a **Formatter** step before mapping.

    <Warning>
      Automated PII detection is not exhaustive. Review `pii_count` and `pii_types[]`, and keep a
      human check in the loop for anything sensitive.
    </Warning>
  </Accordion>

  <Accordion title="Smart Detect Form Fields → Add Fillable Form Fields">
    **Add Fillable Form Fields** takes five parallel lists. Map the matching **Smart Detect Form
    Fields** outputs into each — the picker passes one entry per detected field, so the counts line
    up automatically:

    | Add Fillable Form Fields input | Smart Detect Form Fields output |
    | - | - |
    | **Page Indices** | **Page Index** |
    | **Field Types** | **Field Type** |
    | **Field Names** | **Field Name** |
    | **Bounding Boxes** | **Bounding Box \[x, y, width, height]** |
    | **Field Values** (optional) | **Value** |

    **PDF File** on both steps is the same source document. You can also type the lists by hand —
    one row per field, with each bounding box as `x, y, width, height` in points.
  </Accordion>
</AccordionGroup>

## Multi-file outputs

**PDF to Image** and **Split PDF** produce several files.

* With *Download file*, the result is a single ZIP archive. Zapier has no built-in unzip action,
  so this is usually the harder path.
* With *Download URLs*, the result carries a list of URLs — `file_urls[]` and a `files[]` line-item
  group with `URL`, `contentType`, and metadata per file, plus `first_url` for the common case of
  only needing page one.

Both actions default to *Download URLs* for this reason. To store every output file, loop over the
line-item group with **Looping by Zapier** and upload each `URL` in turn — within the 15-minute
window.

## Renaming outputs

Nitro does not set a meaningful output file name, so name the file on the step that writes it.
A **Formatter by Zapier → Text** step is the usual way to build one from the trigger's file name —
for example stripping the extension and appending `-compressed.pdf`.

When converting between formats, remember to change the extension: a **PDF to Microsoft Office**
output saved as `.pdf` will not open in Word.

## Input formats by action

Most options are dropdowns or plain fields. These are the ones with a format to get right. Page
indices are zero-based everywhere.

| Action | Field | Format |
| - | - | - |
| **Text Extract**, **Delete PDF Pages**, **Ocr PDF**, **Watermark PDF** | Page Indices | Comma-separated: `0,2,5` |
| **Rotate PDF** | Page Indices / Rotation Amounts | Two lists; one amount applies to all pages, or one amount per page |
| **Split PDF** | Page Indices (JSON) | Array of arrays: `[[0,2],[1,3,4]]` — each inner array becomes one PDF |
| **Redact PDF** | Redactions JSON | `[{"pageIndex":0,"boundingBox":[100,100,200,120]}]` — box is `[x, y, width, height]` in points |
| **Watermark PDF** | Bounding Box | `x0,y0,x1,y1` corner coordinates in points, e.g. `210,10,290,60` |
| **Text Bounding Box Extract** | Texts to Search / Regex Flags | Comma-separated; flags are `ignore-case`, `multiline`, `dot-all` |
| **Add Fillable Form Fields** | Bounding Boxes | One row per field: `x, y, width, height` |
| **Fill PDF Form** | Field Mappings | One row per field: field name → value. Checkboxes accept `true`, `yes`, `1`, `x` |
| **Fill PDF Form** | Form Data File | CSV (header row then a values row), JSON, XFDF or FDF — see below |

### Fill PDF Form data files

The data file is passed to Nitro as-is, so it must be in a shape the API accepts:

<Tabs>
  <Tab title="JSON">
    A list of field/value objects — not a flat object:

    ```json theme={null}
    [
      { "field": "first_name", "value": "Jane" },
      { "field": "last_name",  "value": "Doe" },
      { "field": "is_active",  "value": true }
    ]
    ```

    Build it with a **Code by Zapier** or **Formatter** step if the source gives you a flat
    object, or skip the file and use inline **Field Mappings** instead.
  </Tab>

  <Tab title="CSV">
    ```csv theme={null}
    first_name,last_name,is_active
    Jane,Doe,yes
    ```
  </Tab>

  <Tab title="XFDF / FDF">
    Standard Adobe form-data files exported from a PDF tool. Field names must match the AcroForm
    field names in the template.
  </Tab>
</Tabs>

For a handful of values, inline **Field Mappings** is simpler than a file: one row per field,
mapped from the trigger. Provide the file *or* the mappings, not both.
