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.
Hover the collection in Bruno’s sidebar, click the ... menu, and choose Share.
2
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.
3
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.
4
Click Proceed and save the file
Bruno writes a .zip (or a .yml for the single-file shape) to the location you choose.
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.
In the API Client, click Import in the sidebar header and choose Bruno.
Choosing Bruno from the Import menu
2
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.
The Bruno upload step, with the export-shape guidance above the drop zone
3
Review the preview and import
Requestly reads the file and shows what it found. Click Import to create the collection.
The import summary, before anything is created
4
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.
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, 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.
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.
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.
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.
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.
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.
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.