Check if a document is signed
A contract sitting in a queue is worthless until someone confirms it actually has a signature on it. This endpoint reads a document page by page and reports whether a signature mark is present, roughly where it sits, and what kind of mark it looks like, so your workflow can stop guessing and start routing.
Run it online
Run this on our servers with your account. Free tools run in your browser; this one bills your KIT balance per the price above.
The problem it quietly solves
Most intake pipelines treat 'received' and 'signed' as the same event, and they are not. A lender, a staffing agency, or a school registrar can receive hundreds of PDFs a day where some are fully executed and others are missing the one mark that matters. Manually scrolling to the last page of every file to eyeball a signature does not scale, and building your own detector from scratch means labeling thousands of pages just to get started. This endpoint exists so a team can drop that manual check entirely and treat 'is it signed' as a field in their data, not a task on someone's desk.
What you send and what comes back
You post a document to POST /ocr/signature-detect and get a task_id immediately, since scanning every page for marks takes longer than a typical request timeout. Once processing finishes, our global edge delivers a per-page result: whether a signature-like mark was found, its approximate location on the page, and a category such as handwritten, stamped, or a typed name block. You choose whether that result reaches you as a signed webhook the moment it is ready or as a signed link you fetch yourself within 24 hours.
How the detection actually works
The endpoint looks for the visual and structural signals people have used to authenticate paper for centuries: an irregular ink stroke sitting apart from typed text, a stamp's dense circular or rectangular pattern, or a cursive name block near a date line. It does not try to verify whose signature it is or compare it against a reference, and it will not tell you whether the signature is legally binding. What it does well is the narrower, more reliable question: is there a mark here that looks like a signature, and roughly where.
Where it fits in a bigger pipeline
Signature detection is rarely the whole job. Teams typically chain it after a document classify step, so only contracts and consent forms get checked, and before an archiving or e-signature reconciliation step, so unsigned files get bounced back automatically instead of sitting in a shared inbox. Because each call is stateless and billed per request, you can run it on a single upload or fan it out across a nightly batch of thousands without changing how you call it.
Pricing and what you are actually paying for
Each request costs $0.010 plus $0.0575 per page scanned, and a failed task is never billed, we retry automatically up to three times before returning a clear error. There is no free tier, which keeps the endpoint fast and free of the queue noise that abusive traffic causes on unmetered APIs. Access requires prepaid balance; without it, calls return HTTP 402, deliberately, so cost is never a surprise buried in a monthly invoice.
What you can do with it
Loan and lease intake
A lender's document portal automatically flags any uploaded agreement missing a borrower signature before it reaches an underwriter's queue.
HR onboarding packets
An HR system checks every offer letter and NDA for a signature mark before marking a new hire's paperwork complete.
Field service work orders
A field service app confirms a technician's paper work order was countersigned by the customer before closing the ticket.
Notary and closing document review
A title company batch-checks a closing package overnight and routes any page without a signature mark back to the closer the next morning.
FAQ
Does the signature detection API verify whose signature it is?
No. It reports whether a signature-like mark is present and roughly where, not whose it is or whether it matches a reference signature.
Can it tell a stamp apart from a handwritten signature?
Yes, the result includes a category such as handwritten, stamped, or typed name block, so you can filter results by mark type.
What file formats does it accept?
It works with standard scanned and native PDF and common image formats used for document uploads; multi-page files are processed page by page.
Is there a free tier for the signature detection API?
There's no free tier — free tiers get abused and slow everyone down. Access runs on a prepaid ForHosting KIT balance: top up from $10.00 (it never expires) and each request is charged at its published price, so a call with no balance returns HTTP 402. No subscription, no tokens, no invented credits, and a failed task is never charged.
How much does signature detection cost per document?
Pricing is $0.010 per request plus $0.0575 per page, and you are only charged when a page is actually processed successfully.
How do I get the results back?
You receive a task_id immediately, and results arrive by signed webhook when ready or through a signed link valid for 24 hours.
Can I run it on hundreds of documents at once?
Yes, each call is independent and billed per request, so you can call it once per upload or fan it out across a large overnight batch without any change in usage pattern.
What happens if a page fails to process?
The task retries automatically up to three times; if it still fails, you get a clear error and are never charged for that failure.
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, and soon from our app, email and Telegram.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/ocr/signature-detect \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"input":"…"}'const res = await fetch("https://api.kit.forhosting.com/ocr/signature-detect", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"input": "…"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/ocr/signature-detect",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"input": "…"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/ocr/signature-detect", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"input":"…"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"input":"…"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/ocr/signature-detect", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"input": "…"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "ocr.signature_detect",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Limits
max_mb | 25 |
max_pages | 10 |
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |
413 | input_too_large | The file exceeds the size limit. |
422 | task_failed | The task failed after 3 retries. You are never charged for it. |