> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sighting.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Server setup

> Receive, validate, and store screenshot reports on your backend.

Sighting is a browser SDK. Your backend receives, validates and stores reports. The SDK does not provision an endpoint, database, dashboard or AI service.

## Request

```http theme={null}
POST /api/feedback
Content-Type: multipart/form-data; boundary=<browser-generated>
```

| Field        | Required    | Validation                                                      |
| ------------ | ----------- | --------------------------------------------------------------- |
| `text`       | Yes         | String; 1–5000 characters after trimming                        |
| `screenshot` | Yes         | Nonempty PNG file; maximum 5 MiB                                |
| `context`    | Sent by SDK | JSON string containing an object; `{}` if omitted from `send()` |
| `projectId`  | No          | Public project identifier; must be authorized independently     |

A typical context object:

```json theme={null}
{
  "url": "https://app.example.com/checkout",
  "capturedAt": "2026-09-23T12:00:00.000Z",
  "viewport": { "width": 1440, "height": 900 },
  "scroll": { "x": 0, "y": 280 },
  "devicePixelRatio": 2
}
```

This is an illustrative report. Do not trust client-supplied context as verified identity, time, origin or authorization.

## Response

Return 2xx only once you have accepted the report for storage/processing. The included demo responds:

```http theme={null}
HTTP/1.1 201 Created
Content-Type: application/json

{"id":"report-id"}
```

A 204 response also works. The SDK checks the HTTP status, not a `success` property in a JSON body. Return a non-2xx status on failure so the widget retains the draft.

## Local reference server

For maintainers with source repository access, the repository includes `demo/server.mjs`, built with Node's HTTP server and FormData parsing. From the repository root, run `npm ci` then `npm run demo` with Node.js 22+.

It implements:

* Same-origin browser submissions on localhost.
* A 6 MiB request-body limit and 5 MiB screenshot limit.
* Text, MIME type, PNG signature, project ID and context validation.
* A separate generated directory for each saved report.
* A `201` response containing the saved report ID.

It saves `screenshot.png` and `feedback.json` under `demo/uploads/<id>/`. The static demo routes do not serve uploaded reports. This receiver is not included in the npm tarball and is not production infrastructure.

The demo only checks the PNG signature, not a complete image decode. For production, enforce upload limits before buffering, validate/decode images, authorize each project, rate-limit abuse, and keep report storage private. Store a trusted received timestamp server-side.

## Cross-origin endpoints

If your app and API have different origins, your API needs CORS headers for the app's allowed origin. Custom authorization headers normally require a preflight response. Configure your framework's CORS middleware for POST/OPTIONS and the exact custom headers you permit. Also attach appropriate CORS headers to error responses so the SDK can see their status.

The SDK uses `credentials: 'omit'`; browser cookies are never sent. A public `projectId` can route a report, but it does not prove which customer is sending it. Use narrowly scoped, short-lived client credentials if needed. Keep privileged credentials on the server.

Do not set a multipart Content-Type manually in browser code; the browser must provide its boundary. The SDK removes that header if it appears in `headers`.

## Delivery and duplicate reports

The default timeout is 20 seconds. A timeout or connection failure can occur after the server saves the report, so a user retry can create another report. This release has no built-in idempotency key. Add server-side deduplication or extend the integration if exact-once behavior matters.

## Downstream workflows

Once the report is accepted, background jobs can forward it to your team's workflow. Keep Slack/GitHub credentials and AI provider keys on the backend. Treat submitted text as untrusted report content, not as privileged instructions to an agent. The current demo performs no external forwarding.
