postman.ts•7.14 kB
import { request } from 'undici';
import { env } from 'process';
// Read environment variables at module load time. If not provided, use sensible defaults.
const BASE_URL = env.POSTMAN_BASE_URL || 'https://api.getpostman.com';
const API_KEY = env.POSTMAN_API_KEY;
if (!API_KEY) {
throw new Error('POSTMAN_API_KEY is required to use the Postman API.');
}
/**
* Generic helper to perform HTTP requests to the Postman API. Automatically
* injects the X-Api-Key header and parses the JSON response.
*
* @param path Endpoint path beginning with a '/'.
* @param init Additional options passed to undici.request.
*/
async function apiFetch(path: string, init: RequestInit = {}): Promise<any> {
const url = `${BASE_URL}${path}`;
const res = await request(url, {
...init,
headers: {
'X-Api-Key': API_KEY,
'Content-Type': 'application/json',
...(init.headers || {}),
},
});
const text = await res.body.text();
let data: any = null;
try {
data = text ? JSON.parse(text) : null;
} catch {
// ignore JSON parse errors; return raw text
data = text;
}
if (res.statusCode >= 400) {
const message = data?.error?.message || data?.message || text;
throw new Error(`Postman API error ${res.statusCode}: ${message}`);
}
return data;
}
// Workspaces
/**
* Retrieve the list of workspaces accessible to the API key. Returns an array
* of workspace summaries.
*/
export async function listWorkspaces() {
return apiFetch('/workspaces');
}
/**
* Retrieve details of a single workspace by its id. The response includes
* collections, environments, mocks and monitors within the workspace.
*
* @param workspaceId The workspace ID or UID.
*/
export async function getWorkspace(workspaceId: string) {
return apiFetch(`/workspaces/${workspaceId}`);
}
/**
* Extract the list of collections belonging to a workspace. This calls
* getWorkspace and returns the array of collection references.
*/
export async function getCollectionsForWorkspace(workspaceId: string) {
const data = await getWorkspace(workspaceId);
// According to the API docs, the workspace object contains a property
// `collections` with an array of collection references. When not present
// return an empty array to avoid undefined.
return data?.workspace?.collections ?? [];
}
// Collections
/**
* Create a new collection. Accepts a Postman Collection v2 payload. Optionally
* specify a workspaceId to create the collection within a given workspace.
*
* @param collection The collection object to create.
* @param workspaceId Optional workspace ID for associating the collection.
*/
export async function createCollection(collection: Record<string, unknown>, workspaceId?: string) {
const path = workspaceId ? `/collections?workspace=${encodeURIComponent(workspaceId)}` : '/collections';
return apiFetch(path, {
method: 'POST',
body: JSON.stringify({ collection }),
});
}
/**
* Retrieve a collection by its UID. Returns the complete collection
* representation in the Postman Collection v2 format.
*
* @param collectionUid The unique identifier of the collection.
*/
export async function getCollection(collectionUid: string) {
return apiFetch(`/collections/${collectionUid}`);
}
/**
* Update an existing collection. Replaces the existing collection with the
* provided Postman Collection v2 payload.
*
* @param collectionUid Unique identifier of the collection to update.
* @param collection The new collection object.
*/
export async function updateCollection(collectionUid: string, collection: Record<string, unknown>) {
return apiFetch(`/collections/${collectionUid}`, {
method: 'PUT',
body: JSON.stringify({ collection }),
});
}
// Requests
/**
* Create a request inside an existing collection. The Postman API accepts
* request definitions using the Postman Collection v2 format. The request
* will be appended to the end of the collection or inserted into a specific
* folder depending on the parent information provided in the request object.
*
* @param collectionId The ID/UID of the collection to add the request to.
* @param requestBody The request definition as a Postman Collection v2 item.
*/
export async function createRequest(collectionId: string, requestBody: Record<string, unknown>) {
return apiFetch(`/collections/${collectionId}/requests`, {
method: 'POST',
body: JSON.stringify({ request: requestBody }),
});
}
/**
* Retrieve a request item from a collection.
*
* @param collectionId Collection ID or UID.
* @param requestId Unique identifier of the request item.
*/
export async function getRequest(collectionId: string, requestId: string) {
return apiFetch(`/collections/${collectionId}/requests/${requestId}`);
}
/**
* Update an existing request item within a collection.
*
* @param collectionId Collection ID or UID.
* @param requestId Unique identifier of the request item.
* @param requestBody The updated request definition.
*/
export async function updateRequest(collectionId: string, requestId: string, requestBody: Record<string, unknown>) {
return apiFetch(`/collections/${collectionId}/requests/${requestId}`, {
method: 'PUT',
body: JSON.stringify({ request: requestBody }),
});
}
// Responses (examples)
/**
* Create a response example for an existing request. The Postman API uses
* `POST /collections/{collectionId}/responses` with a required query
* parameter `request` that identifies the parent request. The body must
* include a `response` object containing the example definition.
*
* @param collectionId Collection ID or UID.
* @param requestId The request ID to associate the response with.
* @param responseBody The response example definition.
*/
export async function createResponse(collectionId: string, requestId: string, responseBody: Record<string, unknown>) {
const path = `/collections/${collectionId}/responses?request=${encodeURIComponent(requestId)}`;
return apiFetch(path, {
method: 'POST',
body: JSON.stringify({ response: responseBody }),
});
}
/**
* Retrieve a response example by its ID.
*
* @param collectionId Collection ID or UID.
* @param responseId Response ID.
*/
export async function getResponse(collectionId: string, responseId: string) {
return apiFetch(`/collections/${collectionId}/responses/${responseId}`);
}
/**
* Update an existing response example.
*
* @param collectionId Collection ID or UID.
* @param responseId Response ID.
* @param responseBody The updated response definition.
*/
export async function updateResponse(collectionId: string, responseId: string, responseBody: Record<string, unknown>) {
return apiFetch(`/collections/${collectionId}/responses/${responseId}`, {
method: 'PUT',
body: JSON.stringify({ response: responseBody }),
});
}
// Monitors
/**
* Run a monitor synchronously and wait for the run to complete. Returns the
* run results.
*
* @param monitorUid The unique identifier of the monitor.
*/
export async function runMonitor(monitorUid: string) {
return apiFetch(`/monitors/${monitorUid}/run`, {
method: 'POST',
});
}