Back to Surge

Surge API Docs

A no-nonsense guide for testers and technical support. Read it once, you’ll be running bulk API calls in under 5 minutes.

CORS Restriction

Surge executes commands directly in your browser engine. This means that servers without permissive CORS headers will block your requests to protect against cross-site attacks.

If you see a FAILED TO FETCH or CORS POLICY error, the target server is intentionally blocking browser-initiated traffic.

Native Solution

Get the Surge API Request Helper extension for: CORS and Cookies User-Agent Header Injection. If already installed, check that the extension is toggled to "Enabled" and not blocked (check if browser settings/group policies customize allowed/blocking extensions).

What is Surge?

Surge is a browser-based bulk API orchestrator. You upload a spreadsheet of data, design one (or many) API request templates, and Surge fires them all — in parallel or sequentially — row by row. Think of it as “mail merge” for API calls.

It’s built for repetitive tasks: bulk-creating customers, verifying records, migrating data, or smoke-testing an endpoint across thousands of inputs.

API Client Workspace

Surge provides a fully-featured API client workspace alongside the Bulk Runner. Switch to the API Client tab to design, test, and save individual requests.

  • Collections & Folders — Organize requests into collections and nested folders for easy retrieval.
  • Environments & Variables — Define environment variables and switch between environments (e.g., Development, Production).
  • Pre-request & Test Scripts — Write JavaScript to execute before a request is sent (e.g., setting dynamic headers) or after a response is received (e.g., asserting status codes).
  • GraphQL Support — Built-in editor for GraphQL queries and variables.
1

Upload Your Data

Drag & drop (or click to browse) a .csv, .xlsx, or .xls file into the Data Source panel on the left.

Surge will parse the file automatically. Each column header becomes a variable you can reference later.

Example CSV — customers.csv
name,email,phone
Alice,alice@example.com,+84 912 345 678
Bob,bob@acme.co,+84 987 654 321
Charlie,charlie@test.org,+84 901 234 567

After uploading, the panel shows a preview table. You can change the data type for each column (string, number, boolean) — this controls how the value is serialised when it gets injected into request bodies.

2

Design Your Request

In the Request Designer panel, configure the API call you want to make for every row of your spreadsheet.

Method & URL

Pick a method (GET, POST, PUT, PATCH, DELETE, QUERY) and enter the endpoint URL. Use {{column_name}} placeholders to inject values from your spreadsheet.

Example URL
https://api.example.com/customers/{{email}}

Headers

Add headers like Authorization or Content-Type. If you don’t set Content-Type, Surge auto-adds application/json when a JSON body is detected.

Example Header
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...

Query Params

You can add query parameters as key-value pairs. They support {{variable}} interpolation too.

Body (JSON)

Write your JSON body in the built-in Monaco editor. Use the same {{column_name}} syntax.

Example Body
{
  "name": "{{name}}",
  "email": "{{email}}",
  "phone": "{{phone}}",
  "source": "bulk_import"
}

When the column type is set to number or boolean, the value is injected without quotes so the resulting JSON is valid.

cURL Import & Export

Already have a cURL command? Paste it into the URL field — Surge auto-parses method, URL, headers, and body. You can also copy the current template out as cURL to share with colleagues.

Example — Paste a cURL
curl --request POST \
  --url 'https://api.example.com/customers' \
  --header 'Authorization: Bearer token123' \
  --header 'Content-Type: application/json' \
  --data '{
    "name": "{{name}}",
    "email": "{{email}}"
  }'
3

Chain Multiple Steps

Need to call more than one endpoint per row? Click + Add Step in the left sidebar of the Request Designer.

Steps execute sequentially for each row. For example:

  1. Step 1 — Create a customer via POST /customers
  2. Step 2 — Verify the customer via GET /customers/{{email}}

Drag and drop steps to reorder them. If any step fails, the chain is marked as an error but continues to subsequent steps so you still get partial data (unless Stop on Failure is enabled).

Step Output Propagation

Subsequent steps can dynamically reference data returned by previous steps. You can read status codes, headers, and responses from any prior step:

  • Reference by 1-based order index: {{Step 1.response.token}}
  • Reference by clean Step Name: {{Create User.response.id}}
Example URL containing step results
https://api.example.com/customers/{{Step 1.response.id}}/details

Data is recursively flattened into dot-notation paths. You can drill down to any depth (e.g. {{Step 1.response.data.profile.role}}).

4

Execute

The Execution Engine panel lets you configure:

  • Concurrency Limit — how many rows are processed in parallel (1–50). Setting it to 1 means purely sequential.
  • Max Retry Count — the maximum number of attempts (0–10) to retry a request if the response status matches the retry criteria.
  • Retry Status Ranges — a comma-separated list of specific status codes or ranges that trigger a retry.
  • Throttling Delay (ms) — delay staggered between each row's batch execution. Essential for throttling outbound API traffic to prevent HTTP 429 rate limit errors.
  • Row Iterations — configure how many times each row is executed. When greater than 1, each run executes the step chain independently, and subsequent runs are visually grouped under the parent row index (e.g. ↳ Run 2, ↳ Run 3) in the results table.
  • Stop on Failure — when enabled, if any step in a row's chain encounters an error, subsequent steps for that row are automatically skipped to avoid making invalid dependent calls.

Retry Mechanism

When enabled, if a request encounters a network error or returns a status code within the specified ranges, Surge will wait briefly and retry the request up to the maximum count. This helps handle transient issues, rate limiting, and temporary server overloads automatically.

Example Status Ranges
429              // Retry on HTTP 429 (Too Many Requests) only
500-599          // Retry on any 5xx server error range
408, 429, 500-599 // Retry on timeouts, rate limits, or any server errors

Test Row 1

Before blasting all rows, click Test Row 1 to execute only the first row as a dry run. Check the result, inspect the response body, and make sure everything is correct before committing.

Run Engine

Click Run Engine to execute all rows. A progress bar shows how far along you are. You can Stop Execution at any time — already-completed rows are kept, pending rows are cancelled.

5

View & Export Results

After execution, scroll down to the Results table. Each row shows status, status code, response time, and the raw response body.

Column Mapping

Need to pull specific values out of the response? Use column mappings. For each column you define:

  • Name — column header in the export
  • Source — one of: Variable, Request Body, Request Param, Response, Status, Error
  • Path — dot-notation path into the JSON, e.g. data.customer.id
Example — Extracting nested response data
Response JSON:
{
  "data": {
    "customer": {
      "id": "cust_abc123",
      "status": "active"
    }
  }
}

Column Mapping:
  Name: "Customer ID"   → Source: Response  → Path: data.customer.id
  Name: "Status"        → Source: Response  → Path: data.customer.status

Export to Excel

Click the Export button in the results table header to download an .xlsx file with all mapped columns.

Import & Export Workspace

Your entire Surge workspace — uploaded data, request templates, and results — persists in localStorage. You can also export it as a .json file and import it later or share it with a colleague.

  • Export — downloads a surge_workspace_YYYYMMDD_hhmmss.json file
  • Import — opens a file picker, loads the workspace JSON
  • Clear — nukes everything (asks for confirmation first)

Tips & Gotchas

Data Types Matter

If your body expects "quantity": 5 (a number, not a string), change the column type to number in the data source panel. Otherwise it’ll be sent as "quantity": "5".

Empty Variables

If a cell is empty, the {{variable}} is replaced with an empty string. Make sure your API can handle that.

Content-Type Auto-Detection

If you don’t explicitly set a Content-Type header and the body parses as valid JSON, Surge auto-adds application/json.

Large Datasets

Workspace state is stored in localStorage which has a ~5 MB limit. If you’re running thousands of rows, export results frequently and clear stale workspaces.

Concurrency

Higher concurrency = faster, but some APIs rate-limit aggressively. Start with 2–5 and increase only if the target server can handle it.