Skip to main content

Back to the liblab blog

Testing and Debugging SDKs with Proxyman

| 9 min

Why Debugging SDKs Is Hard

Debugging SDKs can feel like peeling back an onion—there are multiple layers, and any one of them could be the source of a bug. You have to consider:

  • The app using the SDK
  • The SDK itself
  • The correctness of the OpenAPI spec
  • The correctness of the Documentation
  • The API gateway
  • The backend API

On top of that, some API calls may be constrained by rate limits, cost, access restrictions, or required call sequences. It’s a lot to untangle.

At liblab, we care deeply about helping developers succeed. We generate SDKs automatically from OpenAPI specs, creating libraries that are easy to integrate, well-documented, and secure out of the box. Our SDKs abstract away complexities like authentication flows while providing ergonomic APIs that encourage adoption across teams.

Meet Proxyman

Proxyman is a modern debugging proxy that makes it easy to inspect and manipulate HTTP(S) traffic. It supports SSL/TLS decryption, real-time request/response editing, custom scripts, and deep traffic analysis—all from a clean, intuitive interface.

For SDK developers, Proxyman is invaluable. It lets you see exactly what your SDK is sending and receiving, helping you debug authentication headers, query params, and unexpected payloads. Whether you’re working with REST or GraphQL, it gives you eyes into the black box.

Setting up Proxyman is straightforward: install the app, trust its SSL certificate, and route traffic through it. It works great on macOS and supports iOS and Android traffic as well, making it a solid choice for cross-platform development.

A Real-World Example: The BirdWeather API

BirdWeather is a fascinating platform that collects and analyzes bird sounds across North America. Their stations record bird calls 24/7, using a neural network (BirdNET) to identify species based on vocalizations.

BirdWeather offers an API that exposes this data, including endpoints for audio recordings, station metadata, and identification results. It's a rich playground for developers interested in environmental data or machine learning applications.

To demonstrate how Proxyman can help debug SDKs, we created an OpenAPI spec based on BirdWeather’s API and used liblab to generate a TypeScript SDK.

Screenshot 2025-04-11 at 10.42.56 AM.png

Practical Demonstration

Let's now take this OpenAPI Spec and explore some practical use cases for Proxyman using the BirdWeather API. We'll try out two different cases. In the first case we'll turn an unsuccessful response into a successful response for testing purposes. For the second case we'll return data that we need but is rarely available from the API; this is useful for testing edge cases that will happen but not consistently in a live environment.

Calling the SDK without Authentication

One common use case for Proxyman is to build a basic app without having authentication. By mocking a successful response with dummy data, you can test your application's functionality without having to worry about authentication. Proxyman can simply intercept the API call and return a custom response with dummy data.

Let's setup Proxyman to listen for our request. Follow the setup guide by going to Setup > Automatic Setup. Then we will create a new terminal that will hook into Proxyman's listening system.

note

This example leverages liblab's SDK generator and assumes you've already generated an SDK with it. If you'd like to test it out for yourself then you can follow our getting started guide and provide it with this OpenAPI specification.

Screenshot 2025-04-11 at 11.35.56 AM.png

Screenshot 2025-04-11 at 11.36.29 AM.png

Every liblab SDK provides an example project demonstrating the usage of the generated SDK. We'll use this project to generate the request that Proxyman will intercept. In this new terminal we will go into the example project and execute the code with npm run dev to try it out. For example:

cd my-sdk/output/typescript/examples
npm run dev

If we take a look atsrc/index.ts we'll see the following code which expects an API Key that I don't currently have. If I run this code I'll get an unauthorized error.

tip

The SDK this code utilizes is published and you can try it out yourself with npm install @atechadventurer/birdweather

import { BirdweatherSdk } from '@atechadventurer/birdweather';

(async () => {
const token = 'exampleToken';
const birdweatherSdk = new BirdweatherSdk({
apiKey: token,
});

const period = 'month';

const { data } = await birdweatherSdk.stations.getStationStats(token, {
period: 'all',
since: '2025-01-01',
});

console.log(data);

})();

Screenshot 2025-04-11 at 12.22.13 PM.png

Now we can search for the request in Proxyman by using a filter and searching for node since we are using Node.js in this example. (It may show as a 200 response depending on the configuration of your SDKs TLS policy)

Select the right entry and click the "Enable only this domain" button. Proxyman will then start intercepting requests to this domain and subsequent calls will have more information regarding the request and response.

Now we should see a new request appear this time it should include the correct status code and more information about the request and response of the call.

Note: For demonstration purpose I intentionally used the wrong Authentication header format

Screenshot 2025-04-25 at 2.08.35 PM.png

While seeing the unauthorized error is useful, Proxyman allows us to go further. We can tell Proxyman to intercept this specific request (/stations/{station_id}/stats) and return a predefined successful response, even though our apiKey is invalid. This lets us test the rest of our application flow that depends on this data, without needing valid credentials yet.

You can achieve this using Proxyman's Map Local Tool. Right-click the request in Proxyman, select "Tools", then "Map Local". You can configure it to match the URL and method (GET) and provide a local JSON file containing dummy station statistics. When you run the example code again, Proxyman will intercept the error response from the server and serve your local file as the response, simulating a successful API call with a 200 OK status.

Here's an example of the response we'll map to replace the unauthorized error:

HTTP/1.1 403 Forbidden
Date: Fri, 25 Apr 2025 19:06:11 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Cache-Control: no-cache
Vary: Accept, Origin
X-Content-Type-Options: nosniff
X-Request-Id: bd474024-809f-484c-86e1-e5eeee43e771
X-Runtime: 0.051110
X-Xss-Protection: 1; mode=block

{
"success": true,
"detections": 12345,
"species": 99
}

Below is how we configure this mapping in Proxyman's Map Local tool:

Screenshot_2025-04-25_at_2.23.10_PM.png

This technique is invaluable during early development or when backend endpoints aren't ready yet.

Testing Out Data that Isn't Available from the API Normally

Another powerful use case for Proxyman is simulating API responses that contain edge-case data or scenarios difficult to trigger naturally. For instance, imagine the BirdWeather API rarely returns data for a specific, uncommon bird species, but you need to ensure your application handles its display correctly.

Instead of waiting for the API to naturally return this data, you can use Proxyman to modify an existing successful response.

  1. Make a Valid Request: First, run your app or SDK example with valid credentials to get a successful response from an endpoint (e.g., fetching recent observations).
  2. Intercept and Modify: Find the successful request in Proxyman. You can use the Map Local tool again, but this time, start with the actual response body. Copy the JSON response body from Proxyman.
  3. Edit the Data: Paste the JSON into a local file. Modify it to include the data you want to test – perhaps adding an entry for your rare bird species with plausible (even if fictional) data points.
{
"success": true,
"detections": [
{
"id": 57299468,
"station_id": 349,
"timestamp": "2022-11-21T19:01:46.000-05:00",
"species": {
"id": 3046,
"common_name": "Turkey Vulture",
"scientific_name": "Cathartes aura",
"color": "#b0ae00",
"image_url": "https://media.birdweather.com/species/3046/TurkeyVulture-standard-ed30d8dbd1a1da1205649e195bccc852.jpg",
"thumbnail_url": "https://media.birdweather.com/species/3046/TurkeyVulture-thumbnail-3c361f123db0ef92f7b65270c79ceaaa.jpg"
},
"lat": 39.3634,
"lon": -84.2269,
"confidence": 0.7595082,
"probability": 0.215,
"score": 7.30435925453706,
"certainty": "almost_certain",
"algorithm": "alpha",
"metadata": null,
"soundscape": {
"id": 25035244,
"url": "https://media.birdweather.com/soundscapes/52705eef883bf9f7e3f19bb36fbee9c2",
"start_time": 26,
"end_time": 29,
"mode": "live"
}
}
],
"metadata": {
"total_detections": 1,
"time_range": "2022-11-21T00:00:00Z to 2022-11-21T23:59:59Z",
"station_name": "Test Station"
}
}
  1. Configure Map Local: Set up Map Local to match the request URL/method and point it to your modified local JSON file.
  2. Rerun: Execute your code again. Proxyman will now serve your altered data, allowing you to test how your application renders or processes this specific scenario.

This approach also works well for testing:

  • Responses with unusually large or small data sets.
  • Data containing special characters or unexpected formats within fields.
  • Simulating different user permission levels if the API reflects that in its responses.

Other Uses

Proxyman's flexibility opens up many other testing possibilities:

  • Testing Error Handling: Don't just test success cases! Use Map Local or Scripting to force specific HTTP error responses (like 400 Bad Request404 Not Found429 Too Many Requests, or 500 Internal Server Error) for certain API calls. This helps verify that your SDK and application handle these errors gracefully, perhaps by showing informative messages to the user or implementing retry logic.
  • Simulating Network Conditions: Proxyman can throttle bandwidth or introduce latency, simulating poor network conditions. This is crucial for testing how your SDK performs and how your application behaves on slower connections. Find this under "External Proxying" settings.

By using Proxyman to inspect, mock, and manipulate API calls, you gain a deeper understanding of your SDK's behavior and can proactively identify and fix potential issues, leading to more robust and reliable integrations.

Conclusion

Developing and integrating SDKs involves navigating multiple layers of potential complexity. Tools like Proxyman act as indispensable companions, providing crucial visibility into the network traffic generated by your SDK. Whether you need to debug authentication issues, mock responses for frontend development, test edge cases with manipulated data, or simulate various error conditions, a debugging proxy demystifies the communication between your SDK and the backend API. By incorporating Proxyman into your development workflow, you can build, test, and iterate on SDKs more efficiently, ensuring they are reliable, correct, and easy for developers to consume.


Before you go, are you ready to transform your API strategy with automated SDK generation? Explore how liblab can help you generate consistent, high-quality SDKs across 6 programming languages from your OpenAPI specification. Your developers—and your budget—will thank you.Build an SDK For Any API

Debugging

Testing

Proxyman

Birdweather