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

# Import from Bruno

> Move a Bruno collection into Requestly, with its requests, environments, scripts, and client certificates.

Bruno keeps every collection as plain-text files on your machine. Requestly imports a collection exported from Bruno 4 in either of Bruno's two native shapes: **Bruno Collection (ZIP)** or **Single File (YAML)**. Both bring across your requests, folders, examples, environments, variables, and scripts. The ZIP brings more, and it is the shape Bruno itself recommends.

## Export your collection from Bruno

<Steps>
  <Step title="Open the Share dialog">
    Hover the collection in Bruno's sidebar, click the `...` menu, and choose **Share**.
  </Step>

  <Step title="Switch to the Export tab">
    The **Share Collection** dialog opens on the **Git** tab, which offers no file at all. Click **Export**. This is where most people get stuck, so check the tab before you look for the format cards.
  </Step>

  <Step title="Choose Bruno Collection (ZIP)">
    Under **BRUNO FORMAT**, pick **Bruno Collection (ZIP)**. Bruno badges it *Recommended* and selects it for you.

    **Single File (YAML)** is supported too, and it is the right pick when you need one file to paste into a gist or attach to an issue. Bruno's exporter drops two things on the way into that shape: client certificates and the OAuth 2.0 token source setting.
  </Step>

  <Step title="Click Proceed and save the file">
    Bruno writes a `.zip` (or a `.yml` for the single-file shape) to the location you choose.
  </Step>
</Steps>

<Warning>
  Do not route through Postman. Exporting Bruno to a Postman collection and then importing that into Requestly loses data twice: Bruno's own dialog warns that gRPC and WebSocket requests are not exported at all in that format, and Postman's format cannot carry Bruno's assertions. Import the Bruno export directly instead.
</Warning>

## Import into Requestly

<Steps>
  <Step title="Open the Import dialog">
    In the API Client, click **Import** in the sidebar header and choose **Bruno**.

    <Frame caption="Choosing Bruno from the Import menu">
      <img className="block dark:hidden" src="https://mintcdn.com/requestly/Aax5kHsGNwEBPk2a/images/import-bruno-picker.light.png?fit=max&auto=format&n=Aax5kHsGNwEBPk2a&q=85&s=63780eb2273ff6545451b343c0675227" alt="Import menu in the API Client sidebar listing Requestly, Postman, Bruno, cURL, gRPCurl, OpenAPI, WSDL, HAR and SoapUI." width="1280" height="800" data-path="images/import-bruno-picker.light.png" />

      <img className="hidden dark:block" src="https://mintcdn.com/requestly/Aax5kHsGNwEBPk2a/images/import-bruno-picker.dark.png?fit=max&auto=format&n=Aax5kHsGNwEBPk2a&q=85&s=aac33e77185fc40fe56dbd983f0288ba" alt="Import menu in the API Client sidebar listing Requestly, Postman, Bruno, cURL, gRPCurl, OpenAPI, WSDL, HAR and SoapUI." width="1280" height="800" data-path="images/import-bruno-picker.dark.png" />
    </Frame>
  </Step>

  <Step title="Select your export">
    Drag the file onto the upload area or click to browse. `.zip`, `.yml`, and `.yaml` are accepted, up to **100 MB**. A ZIP is expanded up to 500 files, with a 50 MB ceiling per file and 100 MB in total.

    <Frame caption="The Bruno upload step, with the export-shape guidance above the drop zone">
      <img className="block dark:hidden" src="https://mintcdn.com/requestly/Aax5kHsGNwEBPk2a/images/import-bruno-upload.light.png?fit=max&auto=format&n=Aax5kHsGNwEBPk2a&q=85&s=aaba54ae388ecb3c3e1716428ae7a6f1" alt="Import Bruno dialog showing guidance to choose the Bruno Collection ZIP export, above a file drop zone." width="1280" height="800" data-path="images/import-bruno-upload.light.png" />

      <img className="hidden dark:block" src="https://mintcdn.com/requestly/Aax5kHsGNwEBPk2a/images/import-bruno-upload.dark.png?fit=max&auto=format&n=Aax5kHsGNwEBPk2a&q=85&s=0fd60a0f267b82b571ce75abfa0ea939" alt="Import Bruno dialog showing guidance to choose the Bruno Collection ZIP export, above a file drop zone." width="1280" height="800" data-path="images/import-bruno-upload.dark.png" />
    </Frame>
  </Step>

  <Step title="Review the preview and import">
    Requestly reads the file and shows what it found. Click **Import** to create the collection.

    <Frame caption="The import summary, before anything is created">
      <img className="block dark:hidden" src="https://mintcdn.com/requestly/Aax5kHsGNwEBPk2a/images/import-bruno-preview.light.png?fit=max&auto=format&n=Aax5kHsGNwEBPk2a&q=85&s=7f3ab92e60c1cb2afdd281845e8de6db" alt="Import summary listing one collection, five requests and one environment, with Back and Import buttons." width="1280" height="800" data-path="images/import-bruno-preview.light.png" />

      <img className="hidden dark:block" src="https://mintcdn.com/requestly/Aax5kHsGNwEBPk2a/images/import-bruno-preview.dark.png?fit=max&auto=format&n=Aax5kHsGNwEBPk2a&q=85&s=33b732046a19bd25d9ccd01292436d2d" alt="Import summary listing one collection, five requests and one environment, with Back and Import buttons." width="1280" height="800" data-path="images/import-bruno-preview.dark.png" />
    </Frame>
  </Step>

  <Step title="Read What needs attention">
    The result screen lists anything that did not come across cleanly, grouped by reason, with a **Show details** toggle for the affected items. Every entry names what to do about it. The next two sections explain what you can expect to see there.

    <Frame caption="The result screen, listing what needs attention">
      <img className="block dark:hidden" src="https://mintcdn.com/requestly/Aax5kHsGNwEBPk2a/images/import-bruno-result.light.png?fit=max&auto=format&n=Aax5kHsGNwEBPk2a&q=85&s=833bd130efc02d14c1ccbf30bedd78b6" alt="Import completed with notes, showing seven items imported and a What needs attention list with an expandable detail toggle." width="1280" height="800" data-path="images/import-bruno-result.light.png" />

      <img className="hidden dark:block" src="https://mintcdn.com/requestly/Aax5kHsGNwEBPk2a/images/import-bruno-result.dark.png?fit=max&auto=format&n=Aax5kHsGNwEBPk2a&q=85&s=61c3179d5c977becebb301420f51b39b" alt="Import completed with notes, showing seven items imported and a What needs attention list with an expandable detail toggle." width="1280" height="800" data-path="images/import-bruno-result.dark.png" />
    </Frame>
  </Step>
</Steps>

## What comes across

* **Requests of all four kinds.** HTTP, GraphQL, gRPC, and WebSocket requests are imported, along with the folder tree that holds them.
* **Examples.** Each saved example is built from its own request, not from its parent, so the URL, method, and body you saved are the ones you get.
* **Environments and variables.** Collection variables, folder variables, and each environment come across. Folder and collection variables of the same name fold together, last one winning, which matches how Bruno resolves them.
* **Authorization.** Every auth mode Bruno records, including requests set to inherit their parent's auth.
* **Scripts.** Pre-request and post-response scripts are translated from Bruno's `bru.*`, `req.*`, and `res.*` API to Requestly's `rq.*` API. Post-response variable captures come across as script lines when the captured value is a plain property path such as `res.body.id`. Anything more involved, a JSONPath selector for example, is reported instead of guessed at.
* **Standalone `.js` files** in the collection folder become [Custom Packages](/api-client/import-packages-into-your-scripts), and `require()` calls in your scripts are rewritten to point at them.
* **The collection's `.env` file**, when you import a ZIP. The keys are created so that `{{apiKey}}` resolves to something you can fill in. Every value is blanked, because a `.env` is the file you deliberately kept out of your collection.
* **Client certificates**, when you import a ZIP into the desktop app. They land in **App Settings → Certificates**.

## Known limitations

Some things are missing from Bruno's export before Requestly ever sees the file, and some have no place to land in Requestly. The import result names every one that applies to your file, so you are told about a loss only when it actually happened.

### Two losses depend on which shape you exported

| What                       | Single File (YAML)                                                                                                                                 | Bruno Collection (ZIP)                                                                                                                                                                                                                                                                            |
| -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Client certificates**    | Not in the export. Re-add them in **App Settings → Certificates**.                                                                                 | Imported on the desktop app. The web app has no certificate store, so they are not added there. Passphrases are never carried across, because Bruno stores them in plain text, and a certificate whose file is missing from the archive is reported by name rather than imported half-configured. |
| **OAuth 2.0 token source** | Not recorded. If a request used an ID token rather than an access token, set it again in the **Authorization** tab, or it will send the wrong one. | Imported.                                                                                                                                                                                                                                                                                         |

### Everything else applies to both shapes

* **Secret environment variable values.** A variable marked secret in Bruno is created with its name and an empty value. Re-enter it, or store it in the [Vault](/api-client/vault/vault).
* **The collection's `.env` file.** A ZIP import creates every key with a blank value, so `{{apiKey}}` resolves to something you can fill in. A single-file export does not carry the file at all. Import it separately with the **Import .env file** option in the Environments sidebar.
* **Collection and folder headers.** Bruno lets a collection or folder define headers that every request below it inherits. Requestly sets headers per request, so those are reported rather than imported. Add them to the requests that need them.
* **WebSocket connection settings.** Bruno's exporter drops the handshake timeout and the keep-alive interval from both shapes. Set them again in the request's **Settings** tab.
* **Per-request transport settings.** Encode URL, timeout, follow redirects, and max redirects live outside the request in Requestly, so they are reported when they differ from Bruno's defaults.
* **Files referenced by path.** A file body, a multipart file row, and a `.proto` schema are stored in Bruno as paths on the machine that exported them. The request is imported and the attachment is not, so re-attach it.
* **gRPC messages beyond the first.** A gRPC request holds one message body in Requestly and a list of them in Bruno, so the first is imported and the rest are reported by name. Copy the others out of Bruno if you need them.
* **GraphQL query bodies.** Bruno's exporter drops the query body from some GraphQL requests. Paste the query and variables again.
* **Assertions, captures, and per-request variables.** Bruno's assertions have no Requestly equivalent and are not rewritten into test scripts. Post-response captures come across as script lines when the captured value is a plain property path such as `res.body.id`; anything more involved is reported instead of guessed at.
* **Folder script order.** Bruno's folder-script execution order (sandwich or sequential) is not in the export. If your folder scripts depend on running in a particular order, check them after importing.
* **OAuth details Requestly does not model.** The OAuth 2.0 credentials placement (Basic header against request body) and the OAuth 1.0 callback URL are reported. The rest of the auth config imports normally.
* **Request and folder tags.** Bruno's labels have no Requestly equivalent, so they are reported and dropped.
* **Non-standard HTTP verbs.** A verb outside `GET`, `POST`, `PUT`, `PATCH`, `DELETE`, `HEAD`, and `OPTIONS`, `PROPFIND` for example, is imported as `GET` and reported. Requestly's method list is fixed, so the verb cannot be kept.
* **Bruno Apps, global environments, and mock servers.** Bruno keeps these outside the collection folder, so no Bruno export contains them. Re-create them in Requestly.

<Note>
  **Script calls with no Requestly equivalent are left in your code unchanged.** They throw when the request runs, which stops the request being sent, so update them before you send. The result screen tells you how many scripts are affected. `bru.runner.stopExecution()` and the `req.set*` mutators are the common cases.
</Note>

## If Requestly refuses the file

Requestly names the file it received rather than half-importing it. Each message tells you what to do next.

* **A `.bru` file.** A `.bru` holds one request and is not read on its own. Export the whole collection from **Share → Export**.
* **A `bruno.json` file.** That is a collection's configuration, not the collection. Export the collection instead.
* **A ZIP with `bruno.json` at its root.** That is a legacy `.bru` collection. Open it in Bruno 4 and export it again from **Share → Export**. A re-export carries everything across, so there is no separate path to take.
* **A ZIP with no `opencollection.yml` at its root.** The archive is not a Bruno collection export. Use the file Bruno wrote under **Share → Export**.
* **A single request file from a ZIP.** A ZIP export stores each request as its own `.yml`. Unzipping and picking one of those imports nothing useful, so Requestly refuses it. Import the archive itself.
* **A Postman-format file exported from Bruno.** Requestly offers to open it with the Postman importer instead. Prefer a direct Bruno export: it brings across your gRPC requests, WebSocket requests, and assertions.

## What's Next?

<CardGroup cols={3}>
  <Card title="Save to a Collection" icon="folder" href="/api-client/api-collections">
    Organize and rename the imported requests
  </Card>

  <Card title="Environments and Variables" icon="brackets-curly" href="/api-client/environments-and-variables">
    Fill in the values that arrived blank
  </Card>

  <Card title="Run the Collection" icon="play" href="/api-client/collection-runner">
    Replay the imported requests in sequence
  </Card>
</CardGroup>
