AI APIs · from our own builds
AI vision API integration: what plant scans and card reading taught us about cost and accuracy
Integrating an AI vision model takes one wrapper that meters every call's tokens, a strict reply format your own code checks, and a test on images like yours before you pick the model. In LeafRanger a plant scan costs about $0.004, forty times our first estimate, because the small model it uses counts a photo as roughly 25,800 tokens. For BogarInfra we tested four models on 29 visiting cards and shipped a mid-size one, which turned 21 of them into usable contacts at $0.00139 a card.
Updated 20 October 2026 · checked against our code and the vendors' documentation
Where have we built this?
- LeafRangerPlant identification, leaf diagnosis and light and soil reading from a photo on a small vision model, every call metered to the user in micro-dollars against a daily cap per plan. Development figures: the app is not in a store and paid plans are off.
- BogarInfraA visiting-card reader in the firm's live admin panel: a vision model transcribes into a strict JSON schema and our code checks phones, PIN codes and GSTINs. Uploads and storage work in production; reading there waits on the client's own AI API key.
What are the numbers and limits to know?
- Measured cost of a LeafRanger plant scan
- About $0.004, at roughly 25,800 tokens per photo on a small vision model (development telemetry)
- Image tokens differ by model
- In LeafRanger the small model counted a photo at about 33 times the tokens of a larger model from the same provider, so the cheaper model was not the cheaper photo
- BogarInfra bake-off winner
- The mid-size model: 21 of 29 cards usable as-is, 2,869 tokens in and 151 out, $0.00139 a card
- The cheapest model in the same test
- $0.00020 a card, 17 of 29 usable as-is; whole 29-card run on the shipped model: about four cents
- Prompt injection
- Ranked first (LLM01) in OWASP's Top 10 for large language model applicationssource, checked 20 October 2026
How do you integrate AI Vision API, step by step?
- 1
Put every call behind one wrapper that reports usage
LeafRanger has one module that talks to the AI provider, with a chat helper and a vision helper. Both take an onUsage callback that receives the response's token counts and model name; a failure inside the callback is caught, so metering can never break a user's request.
- 2
Give the model the narrowest job
BogarInfra's model only transcribes what is printed into a fixed schema: names, company, phones with their labels, emails, websites, addresses, GSTIN and a legibility rating. Everything that can be checked is checked by our code afterwards.
- 3
Prepare the image on the server
Both apps rotate the photo upright from its EXIF data, resize it to 1,600 px on the long edge and re-encode it as JPEG, which drops metadata including GPS. BogarInfra also hashes the prepared image so a photo sent twice is never paid for twice.
- 4
Send the image the way your storage allows
LeafRanger passes a 15-minute presigned URL to a private bucket. BogarInfra sends the card inline as a base64 data URL with detail set to high, because small printed text needs it.
- 5
Ask for a strict reply and handle every failure shape
BogarInfra uses the API's strict JSON-schema reply mode and treats a refusal, a reply cut off by the token limit and invalid JSON as three different errors. LeafRanger uses a plain JSON reply mode and its callers fall back safely when parsing fails.
- 6
Check the answer against your own data
LeafRanger matches the top three plant candidates to its own species catalogue, adds a missing species only after a second model call says it is a real plant with enough confidence, and shows nothing it cannot resolve; a failed real call returns no candidates rather than a made-up one. BogarInfra re-derives phones as E.164, checks PIN codes and validates GSTIN check characters.
- 7
Meter cost and cap usage per plan
Tokens times dollars per million is micro-dollars, so LeafRanger adds integer micro-dollars to one row per user per day. Each plan has a daily cap on scans and chat, and at the cap the API answers 429 with an upgrade message built from the same tier table.
- 8
Test models on images like yours before choosing
For BogarInfra we hand-transcribed 29 licensed card images as ground truth, wrote our predictions down, and ran four models once each through the production code path, scoring field by field.
What went wrong, and how was it fixed?
An estimate forty times too low
A design note priced a plant identification at about $0.0001, assuming a low-detail image of about 100 tokens. The code never sets detail, and the small model counts a photo at roughly 25,800 tokens, so a scan costs about $0.004.
Fix: Every pricing decision uses the metered figure, not the estimate. We have not yet tested whether a low-detail image is accurate enough for the light-reading call.
An unknown model priced as the cheapest
LeafRanger's meter prices any model missing from its table as the cheapest one, so switching to a pricier model by environment variable would under-report spend.
Fix: BogarInfra's reader and bake-off return 'no price on file' for an unpriced model instead of a number. LeafRanger's meter still uses the fallback.
A cheap model that needed its fallback on four cards in ten
The plan was the cheapest small model with a stronger model retrying incomplete cards. It read 57% of names, 45% of companies and 75% of phones, and was incomplete on 12 of 29 cards; the fallback model could not run at all on a provider account that had not been through organisation verification.
Fix: Decided on 11 September 2026: ship the mid-size model alone, with the fallback off until the client's account is verified.
A prompt that dropped Tamil names
The first prompt told the model to return nothing for a name printed only in Tamil. For a Chennai firm that was simply the wrong instruction.
Fix: The prompt now copies names in the script they are printed in, and names are compared letter by letter in any script when scoring.
A quota that two requests can slip past
LeafRanger reads today's count before the call and adds one after it returns, so two scans fired together at the cap can both pass, and a failed identification still uses one of the day's scans.
Fix: Open in LeafRanger: reserve the slot with one conditional update and release it on failure. BogarInfra's per-minute card limit already works atomically.
Production reading waiting on a key
The AI API key we tested BogarInfra's reader with belongs to another of our products and stays off the client's server, so reading in production waits on the client's own key.
Fix: Production keeps every card, says so on screen, and the queue pauses on a missing key, then reads each waiting card once when a key is in place.
What should you check before going live?
- Every call reports its token usage to a meter
- Unpriced models show 'no price on file', not $0
- Replies parsed against a strict schema; refusals, cut-offs and bad JSON handled
- Images re-encoded and stripped of metadata before sending and storing
- Model chosen on a scored test set of images like yours
- Daily caps reserved atomically per user
- Text inside images treated as data in the instructions
- Production runs on the client's own AI provider account and key
Questions about AI Vision API
How many tokens does one photo use with an AI vision model?
It depends on the model and the detail setting, and a cheaper model can count far more. LeafRanger measured about 25,800 tokens per photo on the small model it uses, roughly $0.004, because that model counts an image at about 33 times the tokens of a larger model from the same provider. Check your provider's image-token rules before you price a feature.
Is the cheapest vision model the cheapest per result?
Not in our test. The cheapest model cost $0.00020 a card against $0.00139 for the mid-size model we shipped, but produced four fewer usable contacts out of 29. The whole 29-card run on the shipped model cost about four cents, far less than a director's time spent retyping misread cards.
Should a vision model's answer go straight into the database?
No. In BogarInfra the model's reply is a draft: our code normalises phones, validates PIN codes and GSTIN check characters, and flags rather than silently fixes anything that fails.
Can text in a photo trick the model into doing something else?
Anyone can print anything on a card, so BogarInfra's instructions say the card's text is data to copy, never instructions, the reply is held to a strict schema, and nothing in it is executed or used to choose an action. The worst a hostile card can do is fill a field wrongly, which the checks are there to catch.
Should the image go to the AI API as a URL or inline?
Either works. LeafRanger sends a 15-minute presigned URL to its private bucket; BogarInfra sends the prepared card inline as base64 with detail set to high. Inline avoids exposing a storage URL at all; a URL keeps request bodies small.
Why is chat a paid feature in LeafRanger while scans are free?
Because of what the meter showed. A scan costs about $0.004, so 30 free scans a day is at most about 12 cents per user, while a chat turn on the larger model costs about $0.01. After three days of telemetry in July 2026 we moved chat behind the paid plans and raised the free scan allowance.
Need AI Vision API in your app?
We have built it in production code, including the parts that went wrong. Tell us what your app needs and we'll say what it takes.
Ask about this integrationRelated guides: AWS S3 uploads. Built for: AI features.