Back to News & Insights
Web Development October 1, 2026 · 8 min read

Entitled: An AI Agent That Tells Indians Which Government Schemes They're Owed (Built on Sanity)

This is a submission for the Sanity Challenge, Path One: Ship an Agent That Queries Real Content ...

Entitled: An AI Agent That Tells Indians Which Government Schemes They're Owed (Built on Sanity)

This is a submission for the Sanity Challenge, Path One: Ship an Agent That Queries Real Content

India runs thousands of welfare schemes across central and state governments. Help often doesn't reach people, and the reason isn't that they don't qualify. The eligibility rules are spread over portals and PDFs, written in legal language, and they change by state. The people who need the help most are the ones with the least time and the least second-language English to dig through all that.

Entitled turns that pile into a conversation. Describe your life in plain words, in English or Kannada:

"I'm a widowed farmer in Karnataka with two school-age daughters. We own 1 acre of land."

You get one card per scheme, each with: a verdict: Likely eligible, Worth checking or Probably not the reason, tied to the specific rules that decided it the benefit amount, and a running total of what you're likely owed per year the documents to carry numbered application steps an Apply now link and an Official source link

Eligibility is a chain of conditions: age, income, occupation, land, residence. Then come the exclusions, where you match every positive rule and one clause still disqualifies you. Search over PDFs returns documents. It doesn't evaluate a person against rules.

So in Entitled every rule is a typed object in Sanity, and exclusions are first-class. The clearest demo is the last example pill in the app, "Farmer with a government job":

"I am a farmer with 2 acres of land in Karnataka, but I also work as a government clerk."

This farmer matches every positive PM-KISAN rule: a farmer, with cultivable land in their name. The card still comes back Probably not, with a red Disqualifying rule callout: "Government employees are not eligible." That callout isn't model intuition. It's a document in the dataset:

The agent fetches that rule with a query and reports it. That's how it earns the right to say "you qualify, but...".

What else is in the app Kannada end to end. The interface and the generated answer are both in Kannada, and your language choice persists between visits. Follow-up questions. You can ask "what about scholarships for my daughters?" and the agent reuses your earlier context, so you don't start over. One-tap WhatsApp share. The result is formatted as plain text (✅ / 🟡 / ❌ per scheme, with amounts and apply links), because WhatsApp is how this information actually travels between families in India. Visible progress. A run takes 30 to 45 seconds. Three labelled stages (reading the schemes, checking your situation against the rules, preparing results) show that the system is working.

Demo Live app: https://entitled.varshithvhegde.in/ No login needed. Click an example pill and press the button.

A 60-second path for judges: Click Widowed farmer, Karnataka. You get the likely schemes, the total annual benefit and the documents. Expand a card and press Apply now. The link comes from the dataset, not from the model. Switch to ಕನ್ನಡ and run the same example. The answer comes back in Kannada. Click Farmer with a government job and look at the red Disqualifying rule callout. Ask a follow-up, for example "What about my daughters' education?"

| Type | Role | |---|---| | scheme | name, level (Central/State), state, ministry, categories, benefitAmountAnnual, eligibility[], documentsRequired[] (references), applicationSteps[], sources[], status, supersededBy, lastVerified | | eligibilityRule | attribute (age, income, occupation, landOwnership, bplStatus, residence...), operator, value, plainLanguage, isExclusion | | identityDocument | Aadhaar, ration card and so on, stored once and referenced by many schemes | | applicationStep | ordered steps with a channel (online, office, automatic) and a URL | | source | an official URL and a label, so every claim can be cited |

Four modelling choices carry the project: eligibilityRule is a typed object, not prose. The attribute list is a fixed set, so the agent compares the same vocabulary against what the citizen said. It also keeps plainLanguage, so every rule can be shown to the user in words they understand. isExclusion is a first-class flag. The system prompt makes the agent check every exclusion, because matching every positive rule means nothing if one exclusion matches. Documents are references, not strings. Aadhaar is one document that many schemes point to. The agent dereferences it in the query with documentsRequired[]->{name}. Lifecycle lives in the data. status (active, closed, superseded), supersededBy and lastVerified are modelled so a closed scheme can point to its replacement and a reviewer can mark when a human last checked a rule against the official source.

The agent runs on Inception's Mercury (a diffusion LLM, OpenAI-compatible) through the Vercel AI SDK. It connects over MCP, using @ai-sdk/mcp, to a Sanity Context endpoint in GROQ mode on my dataset. Here is the whole flow, from the question to the cards:

Step by step: Extract. It pulls the citizen's attributes out of the plain-language message: state, age, gender, occupation, income, category, land, family. Orient. It uses the Context tools (initialcontext, schemaexplorer) to see the deployed schema. Fetch. One groqquery retrieves the schemes that have structured rules, with references resolved: Reason. It goes rule by rule against the citizen's attributes and checks every isExclusion rule. The prompt sets a budget of 2 to 4 tool calls, so an answer isn't a crawl. Format. A second pass with tools off turns the answer into a strict JSON shape, and that JSON becomes the cards.

Early on, the formatting pass kept dropping applyUrl and source. A card with no "Apply" button is useless, and prompting harder didn't fix it. So I moved the responsibility out of the model. After the agent answers, the API route looks each scheme up in the dataset and attaches the real apply and source URLs from applicationSteps[].url and sources[].url. The model can reason about eligibility, but it never gets to invent a link.

Want to discuss this further?

Book a free strategy call with our team to see how these insights apply to your specific business goals.

Book a consultation