Source mapsBeta
Upload source maps so minified stack traces can be read.
How it works
- Set
releaseon the SDK, so every error says which build it came from. See Environments and releases. - After each build, upload its source maps for that release.
- When you open the error’s entry on the Logs page, choose De-minify to see the stack trace mapped back to your source files.
Stack traces are stored as they arrived; mapping happens when you ask for it. Grouping and suspect commits use the stack as it arrived.
Upload a source map
/api/v1/{projectId}/sourcemapsX-API-Key required.
| Field | Required | What to send |
|---|---|---|
release | yes | The same string as the SDK’s release option, up to 100 characters. |
originalFileName | yes | The JavaScript file’s name as it appears in stack traces, such as main.3f9a1c.js, or its full URL. |
fileName | yes | The source map file’s name, such as main.3f9a1c.js.map. |
sourceMapData | yes | The source map file’s contents, as a string. |
uploadedBy | no | Who or what uploaded it. |
Uploading again for the same release and file replaces the earlier map. With jq 1.6 or later, a single file looks like this:
jq -n \
--arg release "2.4.1" \
--arg file "main.3f9a1c.js" \
--rawfile map "dist/assets/main.3f9a1c.js.map" \
'{release: $release, originalFileName: $file, fileName: ($file + ".map"), sourceMapData: $map}' \
| curl -fsS -X POST "https://apperioserver.onrender.com/api/v1/your-project-id/sourcemaps" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
--data @-The response is 201:
{
"status": "success",
"message": "Source map uploaded successfully",
"data": {
"_id": "source-map-id",
"projectId": "your-project-id",
"release": "2.4.1",
"fileName": "main.3f9a1c.js.map",
"originalFileName": "main.3f9a1c.js",
"fileSize": 12345,
"createdAt": "2026-01-15T12:00:00.000Z",
"updatedAt": "2026-01-15T12:00:00.000Z"
}
}Upload a whole build
A Node.js script you can run in CI after the build, with the key, project ID and release in environment variables:
import { readdir, readFile } from 'node:fs/promises';
import path from 'node:path';
const dir = 'dist/assets';
const url = `https://apperioserver.onrender.com/api/v1/${process.env.APPERIO_PROJECT_ID}/sourcemaps`;
for (const name of await readdir(dir)) {
if (!name.endsWith('.js.map')) continue;
const response = await fetch(url, {
method: 'POST',
headers: {
'X-API-Key': process.env.APPERIO_API_KEY ?? '',
'Content-Type': 'application/json',
},
body: JSON.stringify({
release: process.env.RELEASE,
originalFileName: name.replace(/\.map$/, ''),
fileName: name,
sourceMapData: await readFile(path.join(dir, name), 'utf8'),
}),
});
if (!response.ok) throw new Error(`${name}: upload failed with ${response.status}`);
console.log(`Uploaded ${name}`);
}RELEASE=2.4.1 node scripts/upload-source-maps.tsNode.js 22.18 and later run this TypeScript file directly. It has no type annotations, so on older versions rename it to .mjs.
Read a stack trace
On the Logs page, open an entry that has a stack trace and a release. Choose De-minify, then switch between Minified and Resolved. Frames without a matching map stay as they were.
Limits
- Only stack traces in the Chrome, Edge and Node.js format (lines starting
at) can be mapped. Firefox and Safari stacks stay minified. - A request body can be up to 5 MB, so very large maps can’t be uploaded yet.
- Upload with the API. The Source Maps page in the dashboard isn’t connected to it yet.
Beta