---
title: "Train an issuer baseline from known-good PDFs"
method: POST
path: "/api/v1/baselines"
tags: ["Baselines"]
---

# Train an issuer baseline from known-good PDFs

`POST /api/v1/baselines`

## Request

- Base URL: `https://tamperlens.com` (the document declares no server; this is the origin it was published from)
- URL: `https://tamperlens.com/api/v1/baselines`
- Auth: none declared

multipart/form-data. Fields: `issuer` (slug, `^[a-z0-9][a-z0-9-]{0,63}$`), `label` (optional human name), and up to 25 file parts, each within the deployment's upload cap.

Send `issuer` and `label` BEFORE the file parts: an invalid slug is then rejected before a single document is parsed.

Each file is parsed **in memory**, reduced to its structural profile, and discarded. Training documents are never written to disk. Files that are not PDFs, or that cannot be parsed, are skipped and reported in `skipped`; they do not fail the request unless none is usable.

Training an issuer that already has a profile MERGES into it, so a baseline can be grown in batches. Training does not consume inspection quota.

**Team plan and up.** The built-in public baselines work on every tier; training private ones answers 403 `plan_required` below Team.

## Response `200`

Default Response

- object
  - `profile` object
    - `issuer` string: Stable slug, e.g. `chase`.
    - `label` string
    - `sampleCount` integer: Genuine documents this profile was built from.
    - `source` 'public-specimen' | 'customer'
    - `builtIn` boolean: true = a profile Tamperlens ships; false = trained by this account.
    - `createdAt` string
    - `updatedAt` string
    - `matchingActive` boolean: false while the profile has fewer than `minSamplesForMatching` samples. Such a profile is stored and reported but every dimension compares as `unknown`.
    - `minSamplesForMatching` integer
    - `dimensions` object[]: Per-dimension summary of the fingerprint. `consistency` is the share of samples carrying the most common value (0-1); a dimension below the engine's threshold can never produce a mismatch.
      - `dimension` string
      - `consistency` number
      - `distinctValues` integer
      - `top` unknown
  - `merged` boolean
  - `filesReceived` integer
  - `filesUsed` integer
  - `skipped` object[]
    - `filename` string
    - `reason` string

## Other responses

- `400`: Default Response
- `401`: Default Response
- `403`: Default Response
- `413`: Default Response
- `422`: Default Response
- `429`: Default Response
- `503`: Default Response

---

[API](https://skmtc.dev/tamperlens/apis/tamperlens-api.md) · [All operations](https://skmtc.dev/tamperlens/apis/tamperlens-api/llms.txt) · [OpenAPI document](https://skmtc.dev/tamperlens/apis/tamperlens-api/revisions/e1b7ae64347b?raw)
