LogoSignature Detection API

Automating signed-contract checks

Automating signed-contract checks

Signature Detection Team

Signature Detection Team

@Signature Detection Team

"Is this contract signed?" is two different questions. One is whether a person can see a signature mark on the page. The other is whether the file is legally executed: the right parties, the right version, maybe a cryptographic signature. This API answers only the first question. An automation built on it should be a hold in a queue, not an auto-approval.

What the check is allowed to do

For each contract:

  1. Send the file to POST https://signature-detector.com/api/detect with header x-api-key.
  2. Read either result.detections (one image) or the top-level pages array (a PDF sent as pdfUrl or pdfBase64). On a PDF, count and creditsUsed are top-level too. creditsUsed is the page count, or 0 when that exact file was cached.
  3. Compare the result to your list of pages that must contain a mark.
  4. If a required page has no detection, stop the filing path and assign a person.
  5. If detections exist, store detectionId, the page number, the boxes, and the confidence scores on the contract record.

A count above zero is not "fully executed." Every detection in the published response has class_name of signature. The API cannot tell your signature from the counterparty's. Sorting two boxes by vertical position is a layout guess you should show to a clerk, not a fact you should write into the system of record as a party name.

Image page vs PDF

A signature page exported as a PNG or JPEG:

import requests
 
response = requests.post(
    "https://signature-detector.com/api/detect",
    headers={
        "Content-Type": "application/json",
        "x-api-key": "your_api_key_here",
    },
    json={"imageUrl": "https://example.com/signature-page.png"},
    timeout=60,
)
data = response.json()
needs_human = response.status_code != 200 or data["result"]["count"] == 0

A full agreement as a PDF uses pdfUrl or pdfBase64 and the loop over data["pages"] from Detect signatures in PDFs with Python. A PDF spends 1 credit per page unless creditsUsed comes back 0. Keep the parsers separate. An image payload does not return pages.

Confidence is not a request setting

The server keeps marks at or above 0.1 and reports result.confidenceThreshold as 0.1. The sample detection in the docs has confidence 0.192. If you treat every returned box as a pass, you will pass weak hits.

A practical split:

  • count == 0 on a required page: hold, reason no-mark-detected
  • every detection under a cutoff you picked, for example 0.5: hold, reason low-confidence
  • at least one detection at or above that cutoff: attach the boxes and continue to the rest of your checklist (dates, names, exhibits)

0.5 is not a tuned threshold from this product. Change it when your reviewers say too much noise is getting through, or that real marks are being held. On an image you can send threshold from 0 to 1 and the server will omit lower scores. The default is 0.1. PDF pages always use 0.1. A value outside 0 to 1 is HTTP 400.

Digital signatures

If the contract was signed in an e-sign tool, the PDF may contain a certificate and no pixels that look like handwriting. This detector will not see the certificate. Do not bounce those files as unsigned solely because count is 0. Either skip this check for files you already know are envelope-completed, or run a PDF signature-dictionary check beside it.

The reverse is also true. A scanned PDF full of ink is not "unsigned" just because Acrobat's signature panel is empty.

What to store

Store the detectionId and the boxes, not a boolean alone. When someone challenges a hold, you can open the page and draw x1, y1, x2, y2. Coordinates in the docs sample (about 321 by 373 through 647 by 502) are absolute pixel positions on the image that was sent, origin at the top-left. Cropping those rectangles is covered in Extract signature crops from bounding boxes. The detect call does not return a cropped image.

imageUrl must be reachable by the API with a plain GET. Put the key in server-side configuration or a workflow credential. The n8n and Zapier post shows the HTTP step if the queue lives in one of those tools.

Credits in a backfile

Each uncached image spends 1 credit, $0.0001. 20,000 signature pages is $2. A repeat of the same bytes does not spend another credit (cached: true on the image response). Running out of credits is HTTP 402 with needsPurchase: true. A detector failure refunds the credit and returns 503 or 500. Credits bought for a migration do not expire, and a new account includes 10 credits to try the queue on real files first. The minimum purchase is $1.

Related: check if a document is signed, contracts, PDF signature detection.

Ready to detect signatures?

Automating signed-contract checks | Signature Detection API