aps_dm_request
Call APS Data Management API endpoints directly for full control over projects, hubs, and folders. Use for pagination, POST/PATCH/DELETE operations, or accessing endpoints not covered by simplified tools.
Instructions
Call any APS Data Management API endpoint (project/v1, data/v1). This is the raw / power‑user tool – it returns the full JSON:API response which can be very large (100 K+ tokens for folder listings). Prefer the simplified tools (aps_list_hubs, aps_list_projects, aps_get_folder_contents, etc.) for everyday browsing. Use this tool when you need full control: pagination, POST/PATCH/DELETE, or endpoints not covered by simplified tools.
Response guidance – when summarising large responses focus on: • Folders: name, id, item count • Files: name, type/extension, size, last modified, version info • Ignore: relationship links, JSON:API meta, and extended attributes unless specifically needed.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| method | Yes | HTTP method. | |
| path | Yes | API path relative to developer.api.autodesk.com (e.g. 'project/v1/hubs' or 'data/v1/projects/b.xxx/folders/urn:adsk.wipprod:fs.folder:co.xxx/contents'). Must include the version prefix (project/v1 or data/v1). | |
| query | No | Optional query parameters as key/value pairs (e.g. { "page[limit]": "200", "includeHidden": "true" }). | |
| body | No | Optional JSON body for POST/PATCH requests. |
Implementation Reference
- src/aps-auth.ts:126-185 (handler)The implementation of apsDmRequest which handles HTTP requests to the APS Data Management API.
export async function apsDmRequest( method: ApsDmMethod, path: string, token: string, options: ApsDmRequestOptions = {} ): Promise<unknown> { const isAbsolute = path.startsWith("http"); if (isAbsolute) { const target = new URL(path); const allowed = new URL(APS_BASE); if (target.host !== allowed.host) { throw new Error( `Refusing to send APS token to foreign host '${target.host}'. ` + `Only requests to '${allowed.host}' are allowed. Use a relative path instead.`, ); } } const normalized = isAbsolute ? path : path.replace(/^\//, ""); const url = new URL(isAbsolute ? normalized : `${APS_BASE}/${normalized}`); if (options.query) { for (const [k, v] of Object.entries(options.query)) { if (v === undefined) continue; if (Array.isArray(v)) { v.forEach((val) => url.searchParams.append(k, String(val))); } else { url.searchParams.set(k, String(v)); } } } const headers: Record<string, string> = { Authorization: `Bearer ${token}`, ...options.headers, }; if ((method === "POST" || method === "PATCH") && options.body !== undefined) { headers["Content-Type"] = headers["Content-Type"] ?? "application/vnd.api+json"; } const init: RequestInit = { method, headers }; if (options.body !== undefined && (method === "POST" || method === "PATCH")) { init.body = JSON.stringify(options.body); } const res = await fetch(url.toString(), init); if (!res.ok) { const text = await res.text(); throw new ApsApiError(res.status, method, url.pathname, text); } if (res.status === 204) { return { ok: true, status: 204 }; } const text = await res.text(); if (!text) { return { ok: true, status: res.status }; } const ct = (res.headers.get("content-type") ?? "").toLowerCase(); if (ct.includes("json")) { try { return JSON.parse(text); - src/aps-auth.ts:112-119 (schema)Type definition for the options allowed in an apsDmRequest call.
export interface ApsDmRequestOptions { /** Query parameters (e.g. page[number], filter[type]). */ query?: Record<string, string | number | boolean | string[] | undefined>; /** Request body for POST/PATCH (JSON). */ body?: unknown; /** Extra headers (e.g. x-user-id, Content-Type). */ headers?: Record<string, string>; }