---
title: Source maps
description: Upload one map per release and file so captured stack frames are mapped back to your source before the error is grouped.
type: how-to
product: monitoring
summary: One map per release and file, and the frames it turns back into your code
updated: 2026-09-28
order: 1
---

A stack from a bundled application points at the build, not at your code. A
Source Map is one uploaded JavaScript source map of one release of a project
environment, and captured stack frames of that release whose file matches
`file_url` are mapped back to the original source before the group is chosen.
[The source_maps collection](/docs/api/source_maps) has every method, its scope
and its examples.

## What a map is keyed by

Two fields identify a map, and one of them decides whether a frame finds it.

<PropertyTable
	properties={[
		{
			name: 'release',
			type: 'string',
			description: 'The release the map belongs to, as sent in ErrorEvent.release. Required.',
		},
		{
			name: 'file_url',
			type: 'string',
			description: 'The minified file the map describes: its URL, or its path. A frame matches on the URL path. Required.',
		},
		{
			name: 'content',
			type: 'string',
			description: 'The source map JSON (revision 3). Written, never read back. Required.',
		},
		{
			name: 'content_sha256',
			type: 'string',
			description: 'SHA-256 of content, hex. Output only.',
		},
		{
			name: 'size_bytes',
			type: 'int64',
			description: 'Size of content in bytes. Output only.',
		},
		{
			name: 'upload_time',
			type: 'timestamp',
			description: 'When the map was uploaded. Output only.',
		},
	]}
/>

The map's id is `smp_<digest>`, and the same release and file always have the
same id. That is the whole of the update story: uploading the same release and
file again replaces the map, so a rebuild that changed only the bundle needs no
cleanup first — the newer upload is the map the frames will be mapped through.

`file_url` is the minified file the map describes: its URL
(`https://app.example.com/assets/index-3f2a.js`) or its path
(`/assets/index-3f2a.js`). A frame matches on the URL path, so either spelling
of the same file finds the map.

## Upload a map

```bash
sylphx observability source-maps create --parent orgs/acme/projects/shop/envs/production --release … --file-url … --content …
```

```bash
curl -X POST "https://api.sylphx.com/v1/orgs/acme/projects/shop/envs/production/source_maps" \
  -H "Authorization: Bearer $SYLPHX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"content":"…","file_url":"…","release":"…"}'
```

```ts
const response = await sylphx.observability.sourceMaps.create({ parent: 'orgs/acme/projects/shop/envs/production', sourceMap: { content: '…', fileUrl: '…', release: '…' } })
```

The `release` here is the same string the emitter sends as
`ErrorEvent.release` ([Errors](/docs/monitoring/errors) covers the capture),
which is what joins a captured frame to this map. Frames are mapped before
grouping runs, so the map belongs in the build that produced the release rather
than in the incident afterwards.

One upload per minified file: a release with three bundles has three maps, each
matching its own file.

## Read the maps back

A map is a lookup, not an archive: reading one returns its release, its file,
its digest and its size, never its content. `get` and `list` need
`observability:read`; the upload needs `observability:write`.

```bash
sylphx observability source-maps list orgs/acme/projects/shop/envs/production
sylphx observability source-maps get orgs/acme/projects/shop/envs/production/source_maps/source-map
```

The list comes back newest first, and it filters on `release` alone: the map
that a release is missing shows up as a file you upload again, at no risk to
the ones already there.

<RelatedDocs
	links={[
		{
			href: '/docs/monitoring/errors',
			label: 'Errors',
			description: 'How a captured stack is parsed, mapped, and then grouped.',
		},
		{
			href: '/docs/monitoring/scrubbing',
			label: 'Scrubbing',
			description: 'What is removed from an occurrence before it is stored.',
		},
		{
			href: '/docs/monitoring/quickstart',
			label: 'Quickstart',
			description: 'Capture an error and read its group back.',
		},
	]}
/>
