Ply is meant to be easy

We invented Ply because automated API testing should be a pleasure. Not a laborious exercise in field-by-field response validations. If tests are easier to build, they're more likely to be comprehensive.

Postman, Insomnia and Thunder Client are awesome tools for sending HTTP requests. Where they fall short is in automated testing. Ply is secure and open-source. No sign-up. No need to export collections for committing to Git. Artifacts are saved directly as human-readable YAML files. Use file system folders to naturally and intuitively organize requests and flows.

Autotesting capabilities

  Ply Postman Insomnia REST-Assured SOAtest ReadyAPI
Graphical Flows
Side-by-Side Results
Low-Code Testing
Auto-Generate Results
GraphQL Support
Dynamic Input Values
Previous Response Refs
Regular Expressions
Open Source
Import from Postman -
VS Code Extension
CI/CD Embeddable
Load Tests (Parallel)


For super complex scenarios, a programmatic approach may be a necessary effort (and Ply supports that too). But for 90% of API testing Ply's workflow-driven, declarative approach is a more maintainable alternative.

For comparison let's look at a simple example: GitHub's REST API for retrieving repository topics. Ply uses YAML for expected/actual results. Here's what a similar test looks like in Postman:

Notice the difference? With Ply you maintain your expected response body as an entire JSON payload embedded in YAML; whereas in Postman you'll need to craft JavaScript to evaluate each and every element. Insomnia tests work much the same way as Postman. Not only are Ply tests much easier to understand, but also they can be auto-generated by capturing a good response.

But what about dynamic values? Isn't JavaScript better for that? Sure it is. That's what template literals were invented for. Read about Ply's intuitive support for dynamic expressions. Most importantly, you'll want to reference properties from previous responses in subsequent requests. Like how ply-demo's starRepository GraphQL query cites the id grabbed by its upstream findRespositoryId request:

This way you can string together requests into a workflow, either declaratively in a YAML request suite, or graphically in a Ply flow.