# Introducing @postman/api-sdk: the official TypeScript SDK for the Postman API

If you've ever tried to automate anything against the [Postman API](https://learning.postman.com/docs/reference/postman-api/make-postman-api-call) from a Node script, you know the drill. You reach for `fetch` or `axios`, hand-roll the `X-Api-Key` header, guess at the shape of a workspace response, and end up staring at an `any` blob wondering which field holds the collection ID. Then a schema changes and your automation quietly rots. We just shipped something that removes most of that pain. [@postman/api-sdk](https://www.npmjs.com/package/@postman/api-sdk) is the official TypeScript SDK for the Postman API, published by Postman on [GitHub](https://github.com/postmanlabs/postman-api-sdk-ts) and npm. It's a typed client for the full Postman surface: workspaces, collections, environments, monitors, mock servers, SDK generation, and more. **The part worth caring about most is how it stays correct.** This SDK isn't hand-maintained. It's regenerated deterministically from the Postman API's own specification, so a change to the API becomes a pull request against the SDK rather than a silent drift you discover in production. And that loop isn't Postman-only: the [Postman SDK Generator](https://www.postman.com/product/sdk-generator/) gives your API the same always-current client. That's the real story here, and I'll come back to it below.

## Why ship an SDK when AI can generate the code for you?

 If you can paste the Postman API docs into Claude or Copilot and get back a working `fetch` call in ten seconds, why bother with a package? Because generated code is non-deterministic and a generated SDK is deterministic. Ask a model for a call it's never made, and it pattern-matches against APIs it saw in training, invents plausible field names, and doesn't flag which parts it made up. You find out at runtime, three commits later. A typed SDK closes that gap: - **The SDK is regenerated from the specification.** The type surface is derived deterministically from the same specification that drives the API itself. It can't disagree with the server, and it can't lag behind a release. Any AI reading those types gets the current reality on the next `npm install`, with no training-cutoff lag.
- **The types are the ground truth.** A model can hallucinate an endpoint name, but the compiler catches it before you can run the code. `sdk.workspaces.createWrokspace` is a red squiggle, not a runtime 404.
- **The AI has real context to work with.** Point Cursor, Copilot, or Claude at your `node_modules/@postman/api-sdk` types and it stops guessing: real method signatures, real enum values, real payload shapes.
 
 So it isn't "AI vs. SDK". It's AI with a deterministic schema versus AI guessing at one. Give a model a specification-derived type surface and its output compiles. ## Why a typed SDK for the Postman API

 The Postman API is already well-documented and stable, so this isn't about hiding it. It's about the ergonomics of calling it from real code, whether that code is written by you, your teammate, or an [AI agent](https://learning.postman.com/docs/postbot/postbot-overview/) sitting in your editor. A typed SDK gives you three things you don't get from raw HTTP: 1. **Autocomplete on every endpoint and every field.** You don't have to keep the API reference open in a second tab.
2. **Compile-time checks against schema drift.** If a required field is missing or a type doesn't match, TypeScript tells you before you ship.
3. **A single client object** that handles auth, base URL, and error shapes consistently across calls.
 
 We've written [about this pattern before](https://blog.postman.com/generating-client-sdks-and-ai-ready-clis-with-postman/) in the context of generating SDKs from collections and [OpenAPI](https://www.openapis.org/) specifications. Typed SDKs are strictly better than raw HTTP for humans, and they're strictly better for AI agents too, since the type surface gives them something concrete to reason about instead of guessing at JSON shapes. `@postman/api-sdk` is that idea applied to the Postman API itself. It's built with the same tooling any Postman customer can use for their own APIs: the [Postman SDK Generator](https://learning.postman.com/docs/sdk-generator/overview). The SDK Generator turns an API definition into a typed client, and we're using it in production on our own public API. ## Always in sync — for our SDK and yours

 This is the part I'm most excited about, and it's the reason a generated SDK beats a hand-maintained one every time. `@postman/api-sdk` is regenerated automatically from the [Postman API's public specification](https://www.postman.com/postman/postman-public-workspace/collection/i2uqzpp/postman-api). Whenever we ship a change to the Postman API — a new endpoint, a new field, a tweaked response shape — a pull request is automatically opened against the [postman-api-sdk-ts repo](https://github.com/postmanlabs/postman-api-sdk-ts) with the regenerated client. Once that PR is reviewed and merged, a new version goes up on npm. In practice, that means: - **You always have access to the newest endpoints.** No "when will they add this to the SDK?" waiting period. If it's in the public specification, it's in the SDK on the next release.
- **Types never lie about the API.** The type surface is derived from the same specification that drives the Postman API itself, so there's no drift between what the SDK claims and what the server actually accepts.
- **You control your update cadence.** Pin a version in `package.json` and bump it when you're ready. Nothing changes under you.
 
 Here's the part that surprises people: this isn't a Postman-only workflow. Every SDK generated by the [Postman SDK Generator](https://www.postman.com/product/sdk-generator/) can be [wired up the same way](https://learning.postman.com/docs/sdk-generator/guides/auto-pr). Point it at your OpenAPI definition, connect it to your source repo, and every change to your specification fires a PR against your SDK repo with the regenerated client. Merge, publish, done. Your customers get the same "always current, never hand-maintained" experience for your API that you get for ours. And because SDK generation is itself part of the Postman API surface, you can drive that loop from this SDK. `sdk.sdks` covers generating an SDK, fetching a download URL, and managing the git connections that raise those pull requests. This is the closed-loop story we've been telling API teams for a while: your API specification is your source of truth, and everything downstream — documentation, mocks, tests, SDKs — regenerates from it. `@postman/api-sdk` is that pattern applied to Postman's own API. If you own an API, the same loop is one SDK Generator project away. ## Getting set up

 To get started, you'll need: - Node.js 18 or higher.
- A [Postman account](https://identity.getpostman.com/signup) (a Free plan is fine).
- A Postman API key. Generate one from **Settings &gt; API keys** as described in Postman's [authentication documentation](https://learning.postman.com/docs/reference/postman-api/authentication). Postman API keys are prefixed `PMAK-...`
 
 Next, install the package. Store your API key in an environment variable. Never commit it. I use [dotenv](https://www.npmjs.com/package/dotenv) locally and a secret manager in CI. Every example in this post constructs the SDK the same way: inline, so you can copy any snippet into a file on its own. The exported class is `PostmanApi`. There isn't a `PostmanSDK` export; if your editor doesn't autocomplete the import, that's the first thing to check. ## Your first script: who am I, and what can I create?

 Here's a hello-world that authenticates, then creates a workspace and a collection inside it. A few things worth pointing out, because they're patterns you'll see everywhere in this SDK: - **Payloads are wrapped in the resource name.** `createWorkspace` takes `{ workspace: { ... } }`, `createCollection` takes `{ collection: { ... } }`. This mirrors the Postman API's own request bodies exactly, so if you already know the API, the SDK feels familiar.
- **Enums are exported for constrained fields.** Instead of passing the string `"personal"`, you pass `CreateWorkspaceWorkspaceType.PERSONAL`. Your editor shows you the whole enum, and TypeScript catches typos before runtime. Resist the urge to reach for `as any` here because that throws away the exact guarantee you installed the SDK for.
- **Different methods have different argument shapes.** `createCollection` takes a body and an options object as two arguments. Other methods, like `putEnvironment` below, take a positional ID first and a body second. Trust the types. Hover over the method and TypeScript tells you exactly what it wants.
- **Responses are wrapped and nullable.** You get `{ user }`, `{ workspace }`, `{ collection }` back, and each is optionally undefined. That's why the example uses `workspace?.id` and `workspace!.id!`. The SDK is being honest about the fact that a create call could conceivably return without the expected field.
 
 That's the whole loop: authenticate, create resources, and get typed responses in return. ## Cleaning up after yourself

 That script just created a real workspace in your real account, and it'll still be there tomorrow. If you're going to run these examples more than once, write the teardown at the same time you write the demo. Deleting the workspace takes the collection and any environments inside it along with it. In the companion repo the examples record what they created to a gitignored JSON file and the teardown reads it back, so `npm run examples:teardown` cleans up without you copying IDs around. ## A more useful example: syncing an environment from your infrastructure

 Here's a pattern I've been using. We have infrastructure config stored in a JSON file, and I want the corresponding [Postman environment](https://learning.postman.com/docs/sending-requests/managing-environments/) to match it exactly. This runs in CI on every merge to `main`. Note the shape of `putEnvironment`: the environment ID is a positional string argument, and the body — with the resource wrapped under `environment` — is the second argument. That's different from `createCollection`, which takes a body first and an options object second. When in doubt, hover the method in your editor and TypeScript shows you the exact signature. If you need to create the environment rather than update an existing one, `createEnvironment` follows the `createCollection` shape instead: body first, then a params object carrying the destination workspace. This composes naturally with other tools. Put the script behind [a GitHub Action](https://docs.github.com/en/actions), gate it on a specific label, and your Postman environments become configuration under version control. I've spent embarrassing amounts of time in the past debugging why a PUT was silently ignored because I nested the body one level too deep. That class of bug is gone. ## Handling errors

 The SDK throws on non-2xx responses, so wrap network calls and check what came back. The important detail — and the one that costs you an afternoon if you get it wrong — is **where the status code lives** on the thrown error object. For 401s and 403s, the fix is almost always the API key. Regenerate it in [**Settings &gt; API keys**](https://learning.postman.com/docs/reference/postman-api/authentication) and make sure the key has access to the workspace you're accessing. If you're on a team plan with [role-based access controls](https://learning.postman.com/docs/collaborating-in-postman/roles-and-permissions/), the key inherits the permissions of the user who generated it. ## Where to go next

 Grab the package from [npm](https://www.npmjs.com/package/@postman/api-sdk), star the [repo on GitHub](https://github.com/postmanlabs/postman-api-sdk-ts), and file issues if you hit rough edges. This is a first release and the team is actively iterating. Because the SDK is regenerated from the Postman API specification on every change, it'll keep pace with the API without any hand-maintenance in between. If you own an API and you've been putting off shipping an SDK, the [Postman SDK Generator](https://www.postman.com/product/sdk-generator/) produces the same kind of typed, auto-updating client for your customers that we're shipping for ours. Point it at your OpenAPI definition, [connect it to your repo](https://learning.postman.com/docs/sdk-generator/guides/auto-pr), and you get the regenerate-on-change loop out of the box. And if you've been putting off automating something against Postman because raw HTTP felt tedious, this is a good weekend to pick it back up.