n4nAI

Building a Postman collection from curl LLM examples

Practical guide to convert curl to Postman collection LLM API examples with ordered steps, runnable code, and verification tips for engineers.

n4n Team5 min read1,040 words

Audio narration

Coming soon — every post will get a voice note here.

When you integrate LLM endpoints, you usually start from a curl snippet in the provider docs. Building a repeatable curl to postman collection llm api workflow turns those one-off commands into shared, variable-driven requests your team can run, test, and extend. This is a concrete entry in the cURL LLM API Cookbook: we take real commands, import them, and harden them into a collection that survives spec changes.

Step 1: Gather representative curl commands

Pull the exact commands you need from the LLM provider or gateway docs. Focus on the endpoints you will actually call: chat completions, embeddings, and maybe token counting. Do not generalize prematurely.

A minimal chat completion call looks like this:

curl https://api.openai.com/v1/chat/completions \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-4o-mini",
    "messages": [{"role":"user","content":"Say hi"}],
    "temperature": 0.7
  }'

An embeddings call is just as important for retrieval pipelines:

curl https://api.openai.com/v1/embeddings \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"text-embedding-3-small","input":"hello world"}'

If you hit a gateway such as n4n.ai, the request shape is identical because it exposes an OpenAI-compatible endpoint. You only swap the base URL and the model string to address any of 240+ models behind that one route. Keep the original curl in a curl.md file so you can diff later when the provider changes a field.

Step 2: Import the curl into Postman

Postman parses curl directly. Open Import → Raw text, paste the command, and let the importer build the request. For the chat example, you get a POST with two headers and a raw JSON body.

The imported request is editable JSON. A cleaned-up version with variables looks like:

{
  "name": "Chat Completion",
  "request": {
    "method": "POST",
    "header": [
      {"key": "Authorization", "value": "Bearer {{api_key}}"},
      {"key": "Content-Type", "value": "application/json"}
    ],
    "body": {
      "mode": "raw",
      "raw": "{\"model\":\"{{model}}\",\"messages\":[{\"role\":\"user\",\"content\":\"{{prompt}}\"}]}"
    },
    "url": "{{base_url}}/v1/chat/completions"
  }
}

The curl to postman collection llm api import is lossless for simple requests, but watch for shell variable expansion. If your curl used $OPENAI_API_KEY, Postman imports the literal string, not the secret. Fix that in the next step. For the embeddings call, repeat the import; Postman creates a second item you can rename.

Step 3: Externalize configuration with environment variables

Create a Postman environment (or a collection variable set) with these keys:

  • base_url: https://api.openai.com (or your gateway URL)
  • api_key: your secret key
  • model: gpt-4o-mini
  • prompt: default test string
  • embed_model: text-embedding-3-small

Reference them with {{var}} syntax. This decouples the request definition from deployment targets. You can maintain one collection and run it against staging, prod, or a local mock by switching environments.

An environment file exported from Postman looks like:

{
  "name": "LLM Local",
  "values": [
    {"key": "base_url", "value": "https://api.openai.com", "enabled": true},
    {"key": "api_key", "value": "sk-...", "enabled": true, "type": "secret"},
    {"key": "model", "value": "gpt-4o-mini", "enabled": true}
  ]
}

For a gateway that honors client routing directives, you might add a router_model variable and pass it in the body or a header. The point is to keep the request template static.

Step 4: Handle authentication securely

Never hardcode keys in the collection JSON you commit to Git. Use Postman’s secret type for api_key or store it in a local environment that is git-ignored.

If your provider supports fine-grained scopes, create a key with only chat.completions access. For OpenAI-compatible gateways, the Authorization: Bearer header is sufficient. Some gateways forward provider cache-control hints; you can add headers like Cache-Control: max-age=3600 if the upstream supports prompt caching.

A robust curl to postman collection llm api setup isolates secrets and uses the same auth pattern across all requests via a collection-level pre-request script:

pm.request.headers.add({
  key: "Authorization",
  value: `Bearer ${pm.environment.get("api_key")}`
});

This removes the need to set the header on every item. If you rotate keys, change one environment field, not ten requests.

Step 5: Parameterize the request body

LLM requests are rarely static. Drive the body from variables and pre-request scripts. Replace the hardcoded message with a variable and optionally load a longer prompt from a file.

In the body tab, switch to raw + JSON and use:

{
  "model": "{{model}}",
  "messages": [{"role": "user", "content": "{{prompt}}"}],
  "temperature": {{temperature}},
  "max_tokens": {{max_tokens}}
}

Define temperature (e.g., 0.7) and max_tokens (512) as collection variables. For batch testing, use a pre-request script to iterate prompts:

const prompts = ["Summarize this", "Translate to French", "Code a quicksort"];
pm.variables.set("prompt", prompts[Math.floor(Math.random() * prompts.length)]);

This turns a single curl example into a fuzzable request. For embeddings, set input from a {{embed_input}} variable so you can test batch sizes.

Step 6: Add tests to verify responses

Postman tests run after the response arrives. For LLM endpoints, assert transport success and structural integrity. A minimal test block:

pm.test("status is 200", () => pm.response.to.have.status(200));

pm.test("response has choices", () => {
  const json = pm.response.json();
  pm.expect(json.choices).to.be.an("array").with.length.greaterThan(0);
  pm.expect(json.choices[0].message.content).to.be.a("string");
});

pm.test("usage is metered", () => {
  const json = pm.response.json();
  pm.expect(json.usage).to.have.property("total_tokens");
});

Your curl to postman collection llm api tests should also catch malformed streaming responses if you use stream: true. In that case, disable the JSON parse test and check for text/event-stream content type.

If you use a gateway with per-token usage metering, the usage object is authoritative. Assert it matches your expected magnitude to detect silent truncation. For embeddings, assert data[0].embedding.length equals the model’s dimension (e.g., 1536).

Step 7: Chain requests for multi-turn flows

Real agents call the model multiple times. Use Postman’s pm.collectionVariables to pass state.

After a completion, store the assistant message:

const json = pm.response.json();
pm.collectionVariables.set("last_reply", json.choices[0].message.content);

The next request can embed {{last_reply}} in a follow-up user message. This mirrors how you would build a conversation loop in code and validates that your prompt templating works before you write a line of Python. You can also chain embeddings → search → chat by saving an embedding vector and injecting it into a system prompt via a pre-request script.

Step 8: Export and version control

Postman collections are JSON. Export as Collection v2.1 and commit to your repo under postman/. Keep environments separate and uncommitted if they hold secrets.

A good convention:

postman/
  llm-api-collection.json
  README.md
env/
  local.postman_environment.json (git-ignored)

Run postman collection run in CI with Newman to block regressions:

newman run postman/llm-api-collection.json -e env/local.postman_environment.json

Newman exits non-zero on test failure, which makes it a cheap smoke test for your LLM integration before a deploy.

Common pitfalls when building a curl to postman collection llm api

Shell variables in curl do not survive import—always replace them with {{vars}}. Trailing slashes on base_url cause double-slash URLs; pick one convention. Model names are case-sensitive and drift between providers; centralize them in variables. JSON body escaping in the raw editor is strict—use the Pretty formatter to avoid stray quotes. Finally, if you test against a gateway with automatic fallback when a provider is degraded, do not assert a specific upstream latency; assert only response shape.

Verifying success

Success means the collection runs end-to-end with zero manual edits. Open Postman, select your environment, hit Runner, and execute the collection. All tests should pass: 200 status, non-empty choices, and a usage block present.

If you are on a gateway that provides automatic fallback when a provider is rate-limited or degraded, simulate a 429 on one upstream and confirm the request still returns a valid completion from the fallback. That validates both your collection and your routing config.

Finally, share the collection with a teammate who has never seen the curl. If they can run it and get a sane response in under two minutes, the curl to postman collection llm api conversion earned its place in your cookbook.

Tagscurlpostmancookbookcli

Written by

n4n Team

The team building n4n — a single OpenAI-compatible API in front of 240+ models, with automatic fallback, load balancing and pay-per-token metering.

More from n4n Team →

All curl llm api cookbook posts →