Methodology

Testing an API When There Is No Specification

No OpenAPI document, no Postman collection, and a client who believes the endpoints are self-explanatory. How to build a surface worth testing, what a specification would have given you, and what to say about coverage in the report.

Pental4 min read

A specification turns an API test into a testing problem. Without one it is a discovery problem first, and the discovery is not free: it is days you are not spending on authorisation logic, which is where the findings usually are.

Ask once more, specifically

"Is there an API specification" is often answered no by somebody who does not have one to hand. Ask for the things that are a specification without being called one.

  • An OpenAPI or Swagger document, including one generated in a development environment and never published.
  • A Postman or Insomnia collection, which developers keep even when documentation does not exist.
  • A gateway configuration, which enumerates routes exhaustively by definition.
  • A client SDK, or the front end itself, which is a specification written in an inconvenient format.
  • Integration tests, which show intended behaviour including the negative cases you would otherwise guess at.

Any of these changes the shape of the engagement, and one of them usually exists.

Build the surface from what the client actually uses

Where nothing exists, the front end is the most productive source, because everything it does is something the API supports. Drive the application through its full workflow with a proxy running, including the paths that need particular roles or particular states, and you have a route inventory that is real rather than guessed.

The limitation is important and should be stated in the report: this gives you the endpoints the interface uses. It does not give you deprecated routes still live, internal endpoints the front end never calls, or the version of the API that the mobile client talks to. Those are frequently where the interesting weaknesses are, precisely because nobody has looked at them.

Fill some of that gap deliberately. Version prefixes in paths often reveal an earlier version still answering. Verbs the interface never sends are worth trying on routes it does use. Identifier patterns in responses tell you what other objects exist without having to guess their shape.

Spend the discovery you saved on authorisation

Once you have a surface, the questions that matter are the same ones a specification would not have answered anyway. A specification tells you an endpoint exists and what it accepts. It does not tell you whether the object identifier in the path is checked against the caller.

Two accounts per role, every endpoint that takes an identifier, and the plain question of whether one account can name another's object. That is where the findings are, it is work a scanner cannot do, and it is the first thing squeezed when discovery has eaten the week.

Say what your coverage was

An API test built from observed traffic has a coverage story, and it belongs in the report rather than in the tester's head.

State how the surface was derived, how many distinct routes you exercised, and what classes of route you know you will have missed. A client reading "forty-one endpoints, derived by driving the web front end through all documented workflows; internal and deprecated routes not reachable from the interface were not enumerated" understands exactly what they have bought. A client reading "the API was tested" does not, and will assume more.

It also makes the case for the specification better than any recommendation could. The next engagement is cheaper and deeper if they produce one, and that argument lands when it is attached to a number.

What a specification would have given you, and what it would not

It is worth being precise about this, because the recommendation to produce one is stronger when it does not overclaim.

A specification gives you the complete route list, the parameters each accepts including the optional ones nobody sends, the expected types, and the versions that are still supported. That is most of the discovery problem and it is the reason a documented API tests deeper in the same number of days.

It does not tell you which of those routes enforces authorisation correctly, whether an object identifier is checked against the caller, whether a field the interface never sends is quietly accepted, or whether the implementation matches its own document. Those are the questions the test is for, and they are unaffected by whether a specification exists. Where a specification is out of date, and many are, it can actively mislead: routes listed that no longer exist, and live routes absent entirely.

So the honest recommendation is not "document your API and it will be secure". It is "document it and the same budget buys more testing of the things documentation cannot answer".

Non-web clients change the surface

Where a mobile or desktop client exists, it is often talking to a different surface from the web front end: an older version, extra endpoints, or authentication that behaves differently because the client cannot be updated as easily.

If mobile is in scope, proxy it and treat what it reveals as part of the inventory. If it is not in scope, say so explicitly in the coverage statement, because a client who has a mobile application will assume its API was covered by an API test unless told otherwise. That assumption is one of the more common gaps between what a report says and what it is read to say.

The same applies to anything machine to machine: partner integrations, webhooks, scheduled jobs with their own credentials. These rarely appear in front end traffic, they frequently authenticate differently, and they are worth asking about directly during scoping rather than discovering on day three.

Scope and coverage are recorded on the phase that produced them rather than being written from memory at the end, so the route inventory you built on day one is still attached to the engagement when the report is assembled, and the same phase carries the checklist you worked through.


Pental Is Built by the People Writing This

Engagement management for testing firms, on a database you own, under your brand, with the AI running on your key.