Signature Comparison Requests
A comparison consists of one questioned signature image and one to five reference images from the same person. The request is sent as multipart/form-data to the POST /v2.4/signature/comparisons endpoint, the API immediately answers 202 Accepted with a comparison id, and the analysis finishes in the background.
Prepare the Images
Each image may be PNG, JPEG or TIFF; a single file is at most 10 MB. Use a scan of at least 300 DPI, or a photo framed so the signature fills most of it. One reference is required, but at least three are recommended: a person's natural signature variation can only be measured across several samples, and comparisons with a single reference get a noticeably lower confidence score.
Send the Request
Put the questioned signature in the questioned field and the references in references[]. The case_reference field is free text and is written into the report as is. Send report=true and a PDF report is produced as well.
Get the Result
There are two ways. If your team has a webhook endpoint, the signature.compared event is sent when the analysis finishes; this is the recommended path in production. Alternatively, poll GET /v2.4/signature/comparisons/{id} every 2 seconds until the status field is completed or failed. A typical run takes 3β8 seconds.
Example Request and Response
curl -X POST https://api.incapon.com/v2.4/signature/comparisons \ -H "Authorization: Bearer $INCAPON_API_KEY" \ -F questioned=@questioned.png \ -F "references[]=@reference-1.png" \ -F "references[]=@reference-2.png" \ -F "references[]=@reference-3.png" \ -F case_reference="2026/1432 E." \ -F report=true
import fs from 'node:fs';
import Incapon from '@incapon/node';
const incapon = new Incapon(process.env.INCAPON_API_KEY);
const comparison = await incapon.signature.comparisons.create({
questioned: fs.createReadStream('questioned.png'),
references: ['reference-1.png', 'reference-2.png', 'reference-3.png'].map((f) =>
fs.createReadStream(f),
),
caseReference: '2026/1432 E.',
report: true,
});
// The result arrives by webhook; here we only store the id
console.log(comparison.id); // cmp_7Hk2...{
"id": "cmp_7Hk2pQx91",
"status": "completed",
"score": 91,
"band": "strong_match",
"models": { "agreeing": 21, "total": 23 },
"reference_count": 3,
"top_features": [
{ "feature": "stroke_curvature", "contribution": 18.4 },
{ "feature": "slant_angle", "contribution": 11.2 }
],
"report_url": "https://api.incapon.com/v2.4/signature/comparisons/cmp_7Hk2pQx91/report",
"credits_charged": 0.40,
"created_at": "2026-10-29T09:14:02Z",
"completed_at": "2026-10-29T09:14:07Z"
}Response Fields
| Field | Type | Description |
|---|---|---|
| status | String | processing, completed or failed. |
| score | Integer | The 0β100 confidence score; details on the Confidence Score Algorithm page. |
| band | String | strong_match, inconclusive or mismatch. |
| models | Object | How many models voted for a match, and the total number of models. |
| top_features | Array | The biometric features that contributed most to the score. |
| report_url | String | The address of the PDF report when report=true. |
status becomes failed, the error.code field holds a value such as signature_not_detected, and no credits are charged.