# Sourcemaps


Bundled JavaScript throws errors in code nobody wrote. The stack trace points at line 1 of `app-4f2b91.js`, which tells you nothing. Upload your sourcemaps and Flare turns those frames back into your own files and line numbers.

## How it works

1. Your build produces JavaScript files and a sourcemap for each one. Upload the maps to Flare with a `version_id` you pick.
2. Configure your client to send that same value as `sourcemapVersionId` on every error report.
3. When a report comes in with a `sourcemapVersionId`, Flare looks up the maps for that version and resolves each stack frame back to your source.

The `version_id` is what ties a deployed bundle to its maps, so it has to survive from build time into the running app. A git commit hash works well. Your package version works too, as long as you bump it every release. Never generate it randomly at upload time: the value baked into the bundle would no longer match the value on the maps, and every frame would silently stay minified.

## Endpoint

`POST https://flareapp.io/api/sourcemaps`

### Headers

| Header | Value | Description |
|---|---|---|
| `Content-Type` | `application/json` | Required |

## Authentication

This endpoint does not use the `x-api-token` header. It reads the `key` field out of the request body instead.

Use your project's public API key, the same one a browser client sends telemetry with. It is safe in build scripts and in your continuous integration pipeline, because it can only upload sourcemaps and send telemetry. See [Sending data](/docs/protocol-javascript/general/sending-data#use-the-public-project-key).

## Payload

| Field | Type | Validation | Description |
|---|---|---|---|
| `key` | string | required | Your project's public API key |
| `version_id` | string | required | Identifier for this build |
| `relative_filename` | string | required | Path to the JavaScript file from the domain root, for example `/js/app.js` |
| `sourcemap` | string | required | The sourcemap, deflated and then base64 encoded |

### Example

```json
{
    "key": "your-project-public-api-key",
    "version_id": "9f2c14b",
    "relative_filename": "/build/assets/app-4f2b91.js",
    "sourcemap": "base64-encoded-deflated-sourcemap-content"
}
```

### Encoding

Compress the sourcemap with raw deflate, then base64 encode the result. Raw deflate means no zlib header and no gzip wrapper, which is worth checking twice because most compression helpers add one by default.

In Node:

```js
import { deflateRawSync } from 'node:zlib';

payload.sourcemap = deflateRawSync(sourcemapJson).toString('base64');
```

In PHP, use `gzdeflate()` rather than `gzencode()` or `gzcompress()`:

```php
$payload['sourcemap'] = base64_encode(gzdeflate($sourcemapJson));
```

## Responses

| Status | Description |
|---|---|
| `204` | Sourcemap stored |
| `403` | Missing or invalid API key, or the team has no active subscription |
| `422` | Validation error |

You get a `422` when:

- The base64 or deflate decoding fails
- The decompressed content is empty or is not valid JSON
- The sourcemap is missing `version`, `sources`, `names` or `mappings`
- The sourcemap `version` is not `3`

## One request per file

A build usually produces several JavaScript files, each with its own map. Send one request per file and reuse the same `version_id` across all of them.

Flare groups maps by `version_id` and then matches individual stack frames using `relative_filename`, so the filename has to match what the browser actually requested.

## Linking errors to sourcemaps

Send `sourcemapVersionId` on the error report with the same value you uploaded:

```json
{
    "sourcemapVersionId": "9f2c14b",
    "exceptionClass": "TypeError",
    "stacktrace": [
        {
            "file": "https://acme.test/build/assets/app-4f2b91.js",
            "lineNumber": 1,
            "columnNumber": 28471
        }
    ]
}
```

Flare resolves each frame's `file`, `lineNumber` and `columnNumber` against the maps for that version.

Send `columnNumber`. A minified bundle puts an entire module on one line, so the line number on its own cannot identify a position.
