Photo checks in your product, through one SDK.
Your users already upload job photos. Sight checks each one and returns pass, fail or needs a person, with the reason. The models, the queue and the results live with us; your side is a few calls.
{
"verdict": "needs_review",
"checking": false,
"checks": [
{
"outcome": "pass",
"reason": "2 hard hats found for 2 workers"
},
{
"outcome": "needs_review",
"reason": "Serial label too small to read",
"ask": "Step closer and retake the label"
}
]
}Download it and play.
The SDK is public. Three steps take you from nothing to a first verdict on a real photo.
- 1
Install the SDK
One package, no dependencies. Open source under the MIT licence.
- 2
Ask us for a key
We set up your account and train a first model on a sample of your photos.
- 3
Hand over a photo
Send one from a real job and read the verdict back.
A handful of calls cover a job.
TypeScript today, with no dependencies, for Node 18+, Bun and Deno. The package is open (MIT); every call is made with your key. The first four are enough; the rest are there when you want them.
- 1
Hand over a photo
Call it when a technician uploads a photo. It answers at once; the checking happens on our side. Sending the same photo twice is harmless.
await checks.addPhoto({ jobId: workOrder.id, // your own id template: "install-completion", slot: "Switchboard", // which photo this is imageUrl: signedUrl, // any https link we can read photoId: image.key, // your own id for the photo }); - 2
Read the verdict
By your own job id, whenever you want it: the verdict, every check with its reason, and what is still missing.
const job = await checks.getJob(workOrder.id); job.verdict; // "pass" | "fail" | "needs_review" | "incomplete" job.checks; // each with outcome, reason, evidence, ask job.checking; // true while photos are still being checked - 3
Close the job
When no more photos are coming. Anything the job required that never arrived now fails.
await checks.complete(workOrder.id); - 4
List what did not pass
Every job at a site that failed or needs a person: the list your quality screen shows.
const qc = await checks.listFailures(site.name); - 5
Take the fast answer first
Checks that need only the rules or the model answer in well under a second; the ones that need a reading say “pending” and follow. Ask for the fast answer, or watch every change.
const now = await checks.addPhoto({ ...photo, wait: "fast" }); // every state as it changes: the fast answer, then the final one for await (const job of checks.watchJob(workOrder.id)) show(job); - 6
Send what the phone already read
If your app read the serial with the phone’s own text reader, send it. Sight uses it instead of reading the photo, answers at once, and marks the evidence as the device’s word.
await checks.addPhoto({ ...photo, readings: { serial: "AB12345678" }, // what the phone read }); - 7
Have results sent to you
Set one https address and every result is posted there, signed, with retries. Check the signature on the raw body in your receiver.
const { secret } = await checks.setWebhook( "https://your-app.example/sight-results" ); // in your receiver const event = await verifyWebhook( rawBody, signatureHeader, process.env.SIGHT_WEBHOOK_SECRET ); saveResult(event.job, event.final);
What you do not have to build.
Every team that adds photo checking ends up building the same machinery. It already exists, so your integration stays thin.
The queue and the workers
Photos are checked in the background. You never run a worker or a retry loop.
The results
Stored on our side and looked up by your own job and photo ids. No tables to add.
The models
Trained on each customer’s photos by our engineers, versioned, and scored before they go live.
The checks
Written as versioned templates, one per kind of job, and frozen once in use so yesterday’s verdict still means the same thing.
Sell it under your own name.
Each API key identifies one of your customers, with its own models, checks, usage and limits. Your customers see your product; they never need to know we are there.
A field-operations platform is built on this. Its connector is thin: it hands over every photo its users take, whichever screen they take it from, and reads the verdicts back by its own work-order ids.
One key per customer
Each key has its own models, checks, usage and limits.
Your name on every screen
Your customers see your product. They never need to know we are there.
Usage you can bill from
Every check is recorded against the key that asked for it.
An SDK that keeps getting sharper.
What is in the SDK and the API today, and what is being built next. Each item is marked with how far along it is.
- Live
TypeScript SDK
On npm as @raku-technologies/sight, MIT licensed, with no dependencies. Generated from the API’s own description, so it cannot drift from it.
- Live
Background checking
Hand a photo over and get an answer at once; the checking, retries and stored results are ours. Read a job by your own id, or list every failure at a site.
- Live
Answers in tiers
The fast answer once the rules and the model have spoken, the final one when readings land. Ask for either with wait: "fast" or "final", or watch every state change with watchJob.
- Live
Results back to your app
Set one https address and Sight posts every result there, signed, with retries for about an hour and a delivery log per job. verifyWebhook checks the signature in your receiver.
- Live
Readings from the device
Send a serial your app already read with the phone’s own text reader. Sight uses it when it fits the template, answers that check at once, and marks the evidence as the device’s word.
- Rolling out
Your own reader
Read crops with your own language model or one hosted where you need it. Sight lists exactly what it needs read, runs the rules, and marks the source on every verdict.
- Rolling out
A templates API
Create, preview and activate checks from your own backend, so your customers can set up their rules inside your product.
- In research
An offline engine
The rule engine in Rust, compiled to WebAssembly and to native code for iOS and Android, tested against the server with one shared suite so the two can never disagree.
- Rolling out
Storage connectors
Amazon S3 read in place by role, then Azure Blob and Google Cloud Storage. Your customers’ photos stay in your customers’ buckets.
- Rolling out
An MCP server
Set up and question checks from Claude or ChatGPT. Going live always takes a person’s yes.
- Rolling out
Your region, your cloud, your marketplace
Processing in your customer’s region or inside their cloud account, and a cloud marketplace listing for buyers who need to purchase that way.
- Rolling out
More SDKs
Python next, generated from the same API description as the TypeScript one.
Get a key and an engineer.
Tell us what your users photograph. We will set up a key, train a first model on a sample of your photos, and help you make the first call.