[GH-ISSUE #3961] [bug]: Unable to import Hoppscotch collections into Postman #1388

Closed
opened 2026-03-16 20:08:01 +03:00 by kerem · 7 comments
Owner

Originally created by @Michele971 on GitHub (Apr 5, 2024).
Original GitHub issue: https://github.com/hoppscotch/hoppscotch/issues/3961

Is there an existing issue for this?

  • I have searched the existing issues

Current behavior

I'm encountering difficulties when attempting to import Hoppscotch collections into Postman. Despite following the recommended steps for migration, the imported collections do not appear in Postman as expected.

The issues persists across multiple attempts to import the collection into Postman.
No error messages or notifications are displayed during the import process, suggesting that the migration is successfull.

I'm seeking guidance, insights, or potential workarounds to successfully import Hoppscotch collections.

Thank you in advance!

Steps to reproduce

  1. export a collection in Hoppsctoch
  2. import the collection into Postman

Environment

Production

Version

Cloud

Originally created by @Michele971 on GitHub (Apr 5, 2024). Original GitHub issue: https://github.com/hoppscotch/hoppscotch/issues/3961 ### Is there an existing issue for this? - [X] I have searched the existing issues ### Current behavior I'm encountering difficulties when attempting to import Hoppscotch collections into Postman. Despite following the recommended steps for migration, the imported collections do not appear in Postman as expected. The issues persists across multiple attempts to import the collection into Postman. No error messages or notifications are displayed during the import process, suggesting that the migration is successfull. I'm seeking guidance, insights, or potential workarounds to successfully import Hoppscotch collections. Thank you in advance! ### Steps to reproduce 1) export a collection in Hoppsctoch 2) import the collection into Postman ### Environment Production ### Version Cloud
kerem 2026-03-16 20:08:01 +03:00
Author
Owner

@jobartim44 commented on GitHub (Apr 18, 2024):

When you say that you are "following the recommended steps", you talk about Postman documentation ?

If you export to JSON format and Postman can't succeed in importing the file is looks like a bug in postman more than in hoppscotch to me.

<!-- gh-comment-id:2064720944 --> @jobartim44 commented on GitHub (Apr 18, 2024): When you say that you are "following the recommended steps", you talk about Postman documentation ? If you export to JSON format and Postman can't succeed in importing the file is looks like a bug in postman more than in hoppscotch to me.
Author
Owner

@imhmdb commented on GitHub (May 21, 2024):

if anyone is facing the same issue and needs a quick/dirty solution, I made this python script to convert Hoppscotch JSON collections into Postman's... the result is not perfect but it was really helpful for my case.

https://gist.github.com/imhmdb/0aa11fd56f6c6d88172dd38e72a703ea

<!-- gh-comment-id:2122232296 --> @imhmdb commented on GitHub (May 21, 2024): if anyone is facing the same issue and needs a quick/dirty solution, I made this python script to convert Hoppscotch JSON collections into Postman's... the result is not perfect but it was really helpful for my case. https://gist.github.com/imhmdb/0aa11fd56f6c6d88172dd38e72a703ea
Author
Owner

@axad1 commented on GitHub (May 23, 2024):

if anyone is facing the same issue and needs a quick/dirty solution, I made this python script to convert Hoppscotch JSON

Thanks. It works.

<!-- gh-comment-id:2126370797 --> @axad1 commented on GitHub (May 23, 2024): > if anyone is facing the same issue and needs a quick/dirty solution, I made this python script to convert Hoppscotch JSON Thanks. It works.
Author
Owner

@anik587 commented on GitHub (Oct 24, 2024):

Here is the updated converter for Hoppscotch to Postman

import json
import os
from urllib.parse import urlparse, parse_qs

# Hardcoded path to the Hopscotch collection JSON file
hopscotch_file_path = "file/path/file.json"  # Replace with your actual file path

# Read the Hopscotch collection from the provided file path
try:
    with open(hopscotch_file_path, 'r') as hopscotch_file:
        hopscotch_collection = json.load(hopscotch_file)
except FileNotFoundError:
    print("The specified file was not found. Please check the path and try again.")
    exit(1)
except json.JSONDecodeError:
    print("Error decoding JSON. Please ensure the file is valid JSON.")
    exit(1)

# Debugging: Print the loaded collection
print("Loaded Hopscotch collection:", json.dumps(hopscotch_collection, indent=2))

postman_collection = {
    "info": {
        "name": hopscotch_collection["name"],
        "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
    },
    "item": []
}

# Function to replace specific values with environment variables
def replace_with_env_vars(value):
    return value.replace("<<url>>", "{{url}}") \
                .replace("<<X-Decoded-Payload>>", "{{X-Decoded-Payload}}") \
                .replace("<<X-Apigateway-Api-Userinfo>>", "{{X-Apigateway-Api-Userinfo}}")

# Function to convert Hopscotch requests to Postman format
def convert_requests(requests, parent_item=None):
    for hopscotch_req in requests:
        if isinstance(hopscotch_req, dict):
            # Parse the URL
            parsed_url = urlparse(replace_with_env_vars(hopscotch_req['endpoint']))  # Use replacement here
            postman_req = {
                "name": hopscotch_req.get("name", "Converted Request"),
                "request": {
                    "method": hopscotch_req['method'],
                    "header": [
                        {"key": h['key'], "value": replace_with_env_vars(h['value']), "type": "text"} for h in hopscotch_req.get('headers', [])
                    ],
                    "body": {
                        "mode": "raw",
                        "raw": hopscotch_req['body']['body']  # Accessing the body content directly
                    },
                    "url": {
                        "raw": replace_with_env_vars(hopscotch_req['endpoint']),  # Replace endpoint with env vars
                        "protocol": parsed_url.scheme,
                        "host": parsed_url.netloc.split('.'),
                        "path": parsed_url.path.lstrip('/').split('/'),  # Remove leading slash
                        "query": [{"key": k, "value": v[0]} for k, v in parse_qs(parsed_url.query).items()]  # Extract all query parameters
                    }
                }
            }

            # Include query parameters from the request's 'params' field, if present
            if 'params' in hopscotch_req:
                postman_req['request']['url']['query'].extend(
                    [{"key": param['key'], "value": replace_with_env_vars(param['value'])} for param in hopscotch_req['params']]
                )

            # If parent_item is provided, append the request to the corresponding folder
            if parent_item:
                parent_item['item'].append(postman_req)
            else:
                postman_collection['item'].append(postman_req)
        else:
            print(f"Unexpected item format: {hopscotch_req}")  # Debugging output

# Function to convert folders
def convert_folders(folders):
    for folder in folders:
        if isinstance(folder, dict):
            postman_folder = {
                "name": folder["name"],
                "item": []
            }
            # Convert requests within this folder
            convert_requests(folder.get("requests", []), postman_folder)
            # Add the folder to the Postman collection
            postman_collection['item'].append(postman_folder)

# Process the top-level folders and their requests
convert_folders(hopscotch_collection.get("folders", []))

# Define the output file path for the Postman collection
postman_file_path = os.path.splitext(hopscotch_file_path)[0] + "_postman_collection.json"

# Write the Postman collection to a file
try:
    with open(postman_file_path, 'w') as postman_file:
        json.dump(postman_collection, postman_file, indent=2)
    print(f"Postman collection saved to: {postman_file_path}")
except Exception as e:
    print(f"An error occurred while writing the Postman collection: {e}")

<!-- gh-comment-id:2434763349 --> @anik587 commented on GitHub (Oct 24, 2024): Here is the updated converter for Hoppscotch to Postman ``` import json import os from urllib.parse import urlparse, parse_qs # Hardcoded path to the Hopscotch collection JSON file hopscotch_file_path = "file/path/file.json" # Replace with your actual file path # Read the Hopscotch collection from the provided file path try: with open(hopscotch_file_path, 'r') as hopscotch_file: hopscotch_collection = json.load(hopscotch_file) except FileNotFoundError: print("The specified file was not found. Please check the path and try again.") exit(1) except json.JSONDecodeError: print("Error decoding JSON. Please ensure the file is valid JSON.") exit(1) # Debugging: Print the loaded collection print("Loaded Hopscotch collection:", json.dumps(hopscotch_collection, indent=2)) postman_collection = { "info": { "name": hopscotch_collection["name"], "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" }, "item": [] } # Function to replace specific values with environment variables def replace_with_env_vars(value): return value.replace("<<url>>", "{{url}}") \ .replace("<<X-Decoded-Payload>>", "{{X-Decoded-Payload}}") \ .replace("<<X-Apigateway-Api-Userinfo>>", "{{X-Apigateway-Api-Userinfo}}") # Function to convert Hopscotch requests to Postman format def convert_requests(requests, parent_item=None): for hopscotch_req in requests: if isinstance(hopscotch_req, dict): # Parse the URL parsed_url = urlparse(replace_with_env_vars(hopscotch_req['endpoint'])) # Use replacement here postman_req = { "name": hopscotch_req.get("name", "Converted Request"), "request": { "method": hopscotch_req['method'], "header": [ {"key": h['key'], "value": replace_with_env_vars(h['value']), "type": "text"} for h in hopscotch_req.get('headers', []) ], "body": { "mode": "raw", "raw": hopscotch_req['body']['body'] # Accessing the body content directly }, "url": { "raw": replace_with_env_vars(hopscotch_req['endpoint']), # Replace endpoint with env vars "protocol": parsed_url.scheme, "host": parsed_url.netloc.split('.'), "path": parsed_url.path.lstrip('/').split('/'), # Remove leading slash "query": [{"key": k, "value": v[0]} for k, v in parse_qs(parsed_url.query).items()] # Extract all query parameters } } } # Include query parameters from the request's 'params' field, if present if 'params' in hopscotch_req: postman_req['request']['url']['query'].extend( [{"key": param['key'], "value": replace_with_env_vars(param['value'])} for param in hopscotch_req['params']] ) # If parent_item is provided, append the request to the corresponding folder if parent_item: parent_item['item'].append(postman_req) else: postman_collection['item'].append(postman_req) else: print(f"Unexpected item format: {hopscotch_req}") # Debugging output # Function to convert folders def convert_folders(folders): for folder in folders: if isinstance(folder, dict): postman_folder = { "name": folder["name"], "item": [] } # Convert requests within this folder convert_requests(folder.get("requests", []), postman_folder) # Add the folder to the Postman collection postman_collection['item'].append(postman_folder) # Process the top-level folders and their requests convert_folders(hopscotch_collection.get("folders", [])) # Define the output file path for the Postman collection postman_file_path = os.path.splitext(hopscotch_file_path)[0] + "_postman_collection.json" # Write the Postman collection to a file try: with open(postman_file_path, 'w') as postman_file: json.dump(postman_collection, postman_file, indent=2) print(f"Postman collection saved to: {postman_file_path}") except Exception as e: print(f"An error occurred while writing the Postman collection: {e}") ```
Author
Owner

@jeroenev commented on GitHub (Feb 4, 2025):

Created an alternate version since my json starts with a list [], so original script errors on hopscotch_collection["name"]
Here's an updated version that deals with multiple collections being exported at once by Hoppscotch, splits them up per collection:

import json
from urllib.parse import urlparse, parse_qs

# Hardcoded path to the Hopscotch collection JSON file
hopscotch_file_path = "./hoppscotch.json"  # Replace with your actual file path

# Read the Hopscotch collection from the provided file path
try:
    with open(hopscotch_file_path, 'r') as hopscotch_file:
        hopscotch_collections = json.load(hopscotch_file)
        if isinstance(hopscotch_collections, dict):
            hopscotch_collections = [hopscotch_collections]
except FileNotFoundError:
    print("The specified file was not found. Please check the path and try again.")
    exit(1)
except json.JSONDecodeError:
    print("Error decoding JSON. Please ensure the file is valid JSON.")
    exit(1)



# Function to replace specific values with environment variables
def replace_with_env_vars(value):
    return value.replace("<<url>>", "{{url}}") \
                .replace("<<X-Decoded-Payload>>", "{{X-Decoded-Payload}}") \
                .replace("<<X-Apigateway-Api-Userinfo>>", "{{X-Apigateway-Api-Userinfo}}")

# Function to convert Hopscotch requests to Postman format
def convert_requests(requests, parent_item=None):
    for hopscotch_req in requests:
        if isinstance(hopscotch_req, dict):
            # Parse the URL
            parsed_url = urlparse(replace_with_env_vars(hopscotch_req['endpoint']))  # Use replacement here
            postman_req = {
                "name": hopscotch_req.get("name", "Converted Request"),
                "request": {
                    "method": hopscotch_req['method'],
                    "header": [
                        {"key": h['key'], "value": replace_with_env_vars(h['value']), "type": "text"} for h in hopscotch_req.get('headers', [])
                    ],
                    "body": {
                        "mode": "raw",
                        "raw": hopscotch_req['body']['body']  # Accessing the body content directly
                    },
                    "url": {
                        "raw": replace_with_env_vars(hopscotch_req['endpoint']),  # Replace endpoint with env vars
                        "protocol": parsed_url.scheme,
                        "host": parsed_url.netloc.split('.'),
                        "path": parsed_url.path.lstrip('/').split('/'),  # Remove leading slash
                        "query": [{"key": k, "value": v[0]} for k, v in parse_qs(parsed_url.query).items()]  # Extract all query parameters
                    }
                }
            }

            # Include query parameters from the request's 'params' field, if present
            if 'params' in hopscotch_req:
                postman_req['request']['url']['query'].extend(
                    [{"key": param['key'], "value": replace_with_env_vars(param['value'])} for param in hopscotch_req['params']]
                )

            # If parent_item is provided, append the request to the corresponding folder
            if parent_item:
                parent_item['item'].append(postman_req)
            else:
                postman_collection['item'].append(postman_req)
        else:
            print(f"Unexpected item format: {hopscotch_req}")  # Debugging output

# Function to convert folders
def convert_folders(folders):
    for folder in folders:
        if isinstance(folder, dict):
            postman_folder = {
                "name": folder["name"],
                "item": []
            }
            # Convert requests within this folder
            convert_requests(folder.get("requests", []), postman_folder)
            # Add the folder to the Postman collection
            postman_collection['item'].append(postman_folder)


# Debugging: Print the loaded collection
print("Loaded Hopscotch collection:", json.dumps(hopscotch_collections, indent=2))
for hopscotch_collection in hopscotch_collections:
    postman_collection = {
        "info": {
            "name": hopscotch_collection["name"],
            "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
        },
        "item": []
    }

    # Process the top-level folders and their requests
    convert_folders(hopscotch_collection.get("folders", []))

    # Define the output file path for the Postman collection
    postman_file_path = f"./converted/postman_{hopscotch_collection["name"]}.json"

    # Write the Postman collection to a file
    try:
        with open(postman_file_path, 'w') as postman_file:
            json.dump(postman_collection, postman_file, indent=2)
        print(f"Postman collection saved to: {postman_file_path}")
    except Exception as e:
        print(f"An error occurred while writing the Postman collection: {e}")

file locations may still need to be updated, or just make a folder with a "hoppscotch.json" file, this converting script + a "converted" folder for the results

<!-- gh-comment-id:2633609864 --> @jeroenev commented on GitHub (Feb 4, 2025): Created an alternate version since my json starts with a list [], so original script errors on `hopscotch_collection["name"]` Here's an updated version that deals with multiple collections being exported at once by Hoppscotch, splits them up per collection: ``` python import json from urllib.parse import urlparse, parse_qs # Hardcoded path to the Hopscotch collection JSON file hopscotch_file_path = "./hoppscotch.json" # Replace with your actual file path # Read the Hopscotch collection from the provided file path try: with open(hopscotch_file_path, 'r') as hopscotch_file: hopscotch_collections = json.load(hopscotch_file) if isinstance(hopscotch_collections, dict): hopscotch_collections = [hopscotch_collections] except FileNotFoundError: print("The specified file was not found. Please check the path and try again.") exit(1) except json.JSONDecodeError: print("Error decoding JSON. Please ensure the file is valid JSON.") exit(1) # Function to replace specific values with environment variables def replace_with_env_vars(value): return value.replace("<<url>>", "{{url}}") \ .replace("<<X-Decoded-Payload>>", "{{X-Decoded-Payload}}") \ .replace("<<X-Apigateway-Api-Userinfo>>", "{{X-Apigateway-Api-Userinfo}}") # Function to convert Hopscotch requests to Postman format def convert_requests(requests, parent_item=None): for hopscotch_req in requests: if isinstance(hopscotch_req, dict): # Parse the URL parsed_url = urlparse(replace_with_env_vars(hopscotch_req['endpoint'])) # Use replacement here postman_req = { "name": hopscotch_req.get("name", "Converted Request"), "request": { "method": hopscotch_req['method'], "header": [ {"key": h['key'], "value": replace_with_env_vars(h['value']), "type": "text"} for h in hopscotch_req.get('headers', []) ], "body": { "mode": "raw", "raw": hopscotch_req['body']['body'] # Accessing the body content directly }, "url": { "raw": replace_with_env_vars(hopscotch_req['endpoint']), # Replace endpoint with env vars "protocol": parsed_url.scheme, "host": parsed_url.netloc.split('.'), "path": parsed_url.path.lstrip('/').split('/'), # Remove leading slash "query": [{"key": k, "value": v[0]} for k, v in parse_qs(parsed_url.query).items()] # Extract all query parameters } } } # Include query parameters from the request's 'params' field, if present if 'params' in hopscotch_req: postman_req['request']['url']['query'].extend( [{"key": param['key'], "value": replace_with_env_vars(param['value'])} for param in hopscotch_req['params']] ) # If parent_item is provided, append the request to the corresponding folder if parent_item: parent_item['item'].append(postman_req) else: postman_collection['item'].append(postman_req) else: print(f"Unexpected item format: {hopscotch_req}") # Debugging output # Function to convert folders def convert_folders(folders): for folder in folders: if isinstance(folder, dict): postman_folder = { "name": folder["name"], "item": [] } # Convert requests within this folder convert_requests(folder.get("requests", []), postman_folder) # Add the folder to the Postman collection postman_collection['item'].append(postman_folder) # Debugging: Print the loaded collection print("Loaded Hopscotch collection:", json.dumps(hopscotch_collections, indent=2)) for hopscotch_collection in hopscotch_collections: postman_collection = { "info": { "name": hopscotch_collection["name"], "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" }, "item": [] } # Process the top-level folders and their requests convert_folders(hopscotch_collection.get("folders", [])) # Define the output file path for the Postman collection postman_file_path = f"./converted/postman_{hopscotch_collection["name"]}.json" # Write the Postman collection to a file try: with open(postman_file_path, 'w') as postman_file: json.dump(postman_collection, postman_file, indent=2) print(f"Postman collection saved to: {postman_file_path}") except Exception as e: print(f"An error occurred while writing the Postman collection: {e}") ``` file locations may still need to be updated, or just make a folder with a "hoppscotch.json" file, this converting script + a "converted" folder for the results
Author
Owner

@anwarulislam commented on GitHub (Mar 4, 2025):

@thetronjohnson, we permit users to export their Hoppscotch collections. However, if Postman wishes to import them, they must integrate that functionality, correct? If we are not planning this, we can proceed to close this issue.

<!-- gh-comment-id:2699297974 --> @anwarulislam commented on GitHub (Mar 4, 2025): @thetronjohnson, we permit users to export their Hoppscotch collections. However, if Postman wishes to import them, they must integrate that functionality, correct? If we are not planning this, we can proceed to close this issue.
Author
Owner

@liyasthomas commented on GitHub (Mar 5, 2025):

I believe @anwarulislam’s statement is accurate. Therefore, I’m closing this ticket because it falls outside the scope of the Hoppscotch project.

<!-- gh-comment-id:2699710626 --> @liyasthomas commented on GitHub (Mar 5, 2025): I believe @anwarulislam’s statement is accurate. Therefore, I’m closing this ticket because it falls outside the scope of the Hoppscotch project.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/hoppscotch#1388
No description provided.