Your cURL Command Works. That Doesn't Make It API Documentation.
“Here's the request. It works on my machine.”
That message can be genuinely helpful. A cURL command gives another developer something concrete to run. It removes the need to reconstruct a URL, header, and payload from three screenshots.
It also leaves a surprising amount unsaid.
Take this fictional request:
curl https://api.example.com/exports \
--header "Authorization: Bearer $API_TOKEN" \
--header 'Content-Type: application/json' \
--data '{"format":"csv","includeArchived":false}'Can format be omitted? Does includeArchived default to false? Is the result a file or a background job? Can a caller retry after a timeout?
The command cannot answer those questions. It shows one input that someone chose.
Start with the example, then write down the rules
Suppose the implementation requires format, accepts csv and json, and treats a missing includeArchived as false. A request schema might look like this:
type: object
required: [format]
properties:
format:
type: string
enum: [csv, json]
includeArchived:
type: boolean
default: falseThis is a schema fragment, not a complete OpenAPI document. It describes intended behavior that you still need to check against the service.
One subtlety matters: putting default: false in a document does not make the server apply that default. Your implementation must do that work. JSON Schema describes default as an annotation, rather than a command to fill in missing values.
This is why importing a request should be the beginning of a documentation task. A tool can organize what the request contains. It cannot establish every rule from one successful example.
Document the response you actually get
Run the request in a safe test environment and inspect the status, headers, and body.
If it creates a background job, document the job response and how callers check its status. If it returns a file, document the media type. If the result depends on format, describe those alternatives explicitly.
Then inspect a failure. Pick one the implementation intentionally supports: invalid input, missing credentials, or insufficient permission.
A handoff that includes one realistic failure gives a client developer something to build recovery behavior around. A success-only example usually leaves that behavior to guesswork.
Remove the things that belong to your session
Before sharing a copied request, inspect it for credentials, cookies, tenant identifiers, internal hostnames, and real customer data. Browser-generated commands can include details that were useful to your session but irrelevant to the recipient.
Replace sensitive values with clear placeholders. Explain how to obtain credentials rather than embedding them. Use a test account that another developer is allowed to access.
Also remove incidental headers only after checking whether they matter. The goal is a small reproducible request, not a mysteriously stripped-down one that fails outside your machine.
Keep the handoff small enough to use
A useful first handoff can fit in a short document:
- A request with safe sample values.
- The required inputs and supported alternatives.
- A representative success response.
- One expected failure and what the caller should do.
- The environment and authentication setup needed to reproduce it.
You can expand it as the integration grows. You do not need to document the entire platform before helping someone call one endpoint.
In Powerduck, importing a cURL request, a Postman collection, or an OpenAPI file gives you a starting point for editing and debugging the API. The useful part of that workflow is reviewing the resulting contract while the working request is still close at hand.
Next time you paste a cURL command into a handoff, add one sentence about what it leaves out. “This example uses CSV; JSON is also supported” is already more useful than “works for me.”
What is the question you most often have to ask after someone sends you a working request?