Manav.id
Regulated ยท 17 min read

The visa appointment was free. Getting one cost two hundred dollars.

Public appointment systems release scarce slots into a queue that scripts can enter faster than people. The slots are then resold, and the agency's answer is to cancel bookings, which lands on the applicant rather than the broker. The structural fix is not better bot detection. It is a booking that cannot be handed to anyone else.

Picture a student in Hyderabad with an admission letter for a course that starts in January. She needs a visa interview. The consular calendar has shown no availability for eleven weeks. She has been told, correctly, that slots are released in batches without warning, so she sets an alarm for the small hours and refreshes.

At some point in the night the calendar fills with green. She clicks the first date, and by the time the confirmation page loads it is gone. She clicks the next, and it is gone. Inside ninety seconds the calendar is grey again. She has watched an entire release cycle happen and has not been slow, exactly. She has been human.

The next morning a WhatsApp contact offers her a confirmed interview date for a fee. The fee is not for the appointment, which is free, nor for any service she could not have performed herself. It is for the fact that somebody else's software was awake at 3am and hers was not.

That figure in the headline is illustrative. Broker prices for public appointment slots are advertised openly and vary enormously by country, appointment class and urgency, and no one publishes a systematic price index, which is itself part of the problem. The number is not what matters. What matters is that a public good with a price of zero reliably acquires a secondary market price, and that the people paying it are, almost by definition, the ones with the least ability to.

Short answer. Appointment bots win because a booking is a transferable database row. Detection tools try to spot the script, which is a race the agency loses. The structural fix is to bind each booking to a present human's device key at the moment of claiming, and to check the same key at the counter. A slot that cannot be transferred cannot be resold, so the resale market collapses without the agency ever identifying a bot.

What actually happens when a batch of appointment slots opens?

It helps to walk the mechanism slowly, because the popular description, that bots grab the slots, hides the part that the fix depends on.

Step one: the monitor

Almost no booking system releases inventory continuously. Slots appear in batches, when a post adds capacity, when a cancellation window closes, or when a scheduled job publishes the next month. A monitoring script does not attempt to book anything. It polls whichever endpoint the calendar page itself calls, usually a JSON interface returning available dates, on an interval measured in seconds. This is cheap, it looks like a slightly enthusiastic user, and there are often several thousand of them running.

Worth noting, because it matters later: a monitor that watches for availability and alerts a human is not obviously doing anything wrong. It is a refresh button with more stamina. Some published services are only this.

Step two: the claim

When availability appears, the operation has to convert it into a held slot faster than a person can read the screen. This requires an authenticated session, because schedulers almost always require an account, so the operator maintains a pool of them. Some are created with placeholder details. Many, and this is the uncomfortable part, are the customers' own accounts, handed over with credentials, because the customer wants the service to book on their behalf.

The claim itself is one request. The window between a slot becoming visible and being taken can be under two seconds, which is why the student in Hyderabad watched a calendar drain while she was still reading it.

Step three: the transfer

This is the step that makes it a market, and it is the step almost nobody analyses.

A held slot only has resale value if it can be moved to whoever pays. There are three ways, and each one depends on the booking being a mutable record rather than a commitment by a specific person. The operator books directly in the customer's name using credentials the customer supplied. Or the operator books under a placeholder, then cancels and rebooks in the customer's name in a coordinated swap timed so nobody else can take the released slot. Or the operator simply sells the account, credentials and all, with the appointment inside it.

Every one of those requires the same underlying property: the appointment belongs to a name in a database, and names in a database can be edited, transferred, or sold along with the login that controls them. That property is the actual vulnerability. The speed of the script is only how the inventory is acquired.

Why is a free appointment worth two hundred dollars?

Because the slot is not the product. Access to a date is the product, and the date has a deadline attached to it.

A visa interview in October rather than February is the difference between starting a degree this academic year and deferring twelve months. A road test before a job start date is the difference between taking a driving job and not. A passport appointment this week rather than next month is the difference between reaching a dying relative and not. The willingness to pay is not proportional to the value of the appointment. It is proportional to the cost of missing the deadline, and that cost can be a year of someone's life.

Scarcity plus a deadline plus transferability is the classic setup for scalping, and it is precisely the same structure as concert tickets, which we have written about elsewhere. The difference is the population. A person priced out of a concert misses a concert.

Who actually pays for appointment scalping?

Say this part plainly, because it tends to get lost under the technical framing. An automated arbitrage on a free public service is a regressive tax. Its incidence falls on the people least able to bear it and least able to complain effectively.

The applicant who can pay a broker gets the appointment. The applicant who cannot, waits. The applicants in the second group are disproportionately poorer, disproportionately migrants dealing with a foreign bureaucracy in a second language, and disproportionately people who do not know that a secondary market exists at all and simply conclude that the system is full. Meanwhile the agency's costs go up, because it is now funding bot mitigation, cancellation operations, complaint handling and, eventually, a legislative inquiry.

Public scheduling systemWhat the slot actually controlsWho is harmed when it is captured
Consular visa interviewsCourse start dates, employment start dates, family eventsStudents, workers on employment based visas, families separated by borders
Passport and travel document officesAbility to travel at all, often urgentlyPeople handling a bereavement or a medical emergency abroad
Driving licence and road testsEmployment for anyone who drives for a livingNew drivers, delivery and haulage workers, rural residents
Trusted traveller and border enrolmentConvenience at the borderFrequent travellers. Lowest real harm, highest willingness to pay, which distorts the market
Public healthcare appointmentsTiming of diagnosis and treatmentPatients in capacity constrained systems, where the queue is the rationing mechanism
Court clerk and registry windowsFiling deadlines, licences, statutory recordsLitigants without representation, small businesses, anyone facing a limitation period

Note the pattern in the right hand column. In every row except one, the harm concentrates on people with a deadline they did not choose and no budget for an intermediary.

Why do CAPTCHAs and rate limits keep losing?

They are the same category of control as everything else that is currently losing across fraud and abuse, and they lose for the same reason. They attempt to determine, probabilistically, whether a request came from a person, using signals the requester controls.

Challenge systems are defeated by solver services, which are cheap when the prize is worth hundreds of dollars. Rate limits are defeated by residential proxy pools, which resell consumer connections so that requests arrive from ordinary home addresses in the target country. Device signals are defeated by emulation, and by the plain fact that a real browser on a real machine is easy to obtain.

None of this means the products are bad. Challenge and rate limiting genuinely remove enormous volumes of low effort automation, and a scheduler without them would be worse. It means they are the wrong last line for a resource this valuable. We have set out the general form of this argument in detection debt: spending rises, detection rates fall, and the gap is filled with operational cleanup.

The cleanup is the part that hurts people

In late March 2025, the United States Embassy in India publicly announced that it was cancelling approximately 2,000 visa appointments that had been booked by bots in violation of its scheduling policies, describing the action as targeting bad actors manipulating the system (Consular Team India public announcement, March 2025). Taken on its own terms this is the correct enforcement response, and the post deserves credit for saying publicly what most agencies handle quietly.

But look at where the cancellation lands. Many of those bookings were made for real applicants who paid an agent, frequently without understanding that the agent was running a script or that using one voided the booking. The bot operator loses inventory it acquired at near zero cost and re acquires it on the next release. The applicant loses a date, and possibly a semester.

This is the deepest problem with detection as the primary control here. Detection produces a decision after the harm has been distributed, and the only lever available at that point is to cancel, which necessarily strikes the person holding the booking rather than the person who took it.

What would make an appointment slot impossible to resell?

Stop trying to work out whether the claimant is a bot. Change what a booking is.

Today a booking is a row: a slot identifier, a name, an account. Rows are transferable. Instead, make a booking a commitment by a specific human, evidenced by a signature from a key held on that person's own device, produced at the moment the slot is claimed. The agency stores the resulting receipt against the slot. At the counter, the person who turns up signs a fresh challenge with the same key, and the clerk's terminal checks that it matches.

The analogy is a named train ticket with photo identification at the barrier, except that the identification never leaves the passenger's pocket. The reason a named ticket kills touting is not that the railway got better at spotting touts. It is that the ticket stopped being bearer instrument.

What is actually signed

The signature covers the specific claim, not a generic login. A canonical payload looks like this, and the applicant's device signs the hash of it:

{
  "action":       "appointment.claim",
  "system":       "consular.hyd.niv",
  "slot_id":      "2026-11-04T09:20:00+05:30#B1B2#c7",
  "appt_class":   "student",
  "applicant_ref": "sha256(passport_no + post_salt)",
  "released_at":  "2026-09-30T04:00:00Z",
  "claimed_at":   "2026-09-30T04:00:11Z",
  "nonce":        "9f2c...a1"
}

Two details are worth pausing on. First, applicant_ref is a hash, not a passport number. The consulate already holds the passport details from the application itself, so the scheduler has no reason to hold them a second time, and the identity layer is deliberately built to know nothing it does not need. Second, claimed_at minus released_at is now a signed, non repudiable measurement of how fast the queue is being drained, which gives the agency real fairness data for the first time.

What happens at the counter

The check is two verifications and no lookup:

def verify_at_counter(receipt, live_assertion, published_key):
    # 1. Was this slot claimed with a valid, unaltered receipt?
    payload = canonical_json(receipt["payload"])
    if not ed25519_verify(published_key, receipt["sig"], sha256(payload)):
        return "receipt invalid"

    # 2. Is the person standing here the person who claimed it?
    if live_assertion["key_id"] != receipt["payload"]["key_id"]:
        return "slot was transferred"          # broker resale, caught here

    if not webauthn_verify(live_assertion, challenge=counter_nonce()):
        return "no live presence"

    return "same human, same slot"

Both checks run against a published key, offline, with no call back to any vendor. That matters for a consular post with an unreliable link, and it matters for a procurement officer who does not want a queue that stops when a supplier has an outage.

The elegant part: the slot service becomes legitimate

Here is the consequence that makes this worth doing rather than merely correct.

Under presence bound booking, the monitoring business survives and the hoarding business does not. A service can still watch for availability and alert its customers the instant a batch drops. What it can no longer do is claim inventory and hold it, because a claim now requires a signature from a person who is present, and it cannot resell a claim it did make, because the key cannot be handed over.

So the design does not ban slot services. It converts them into what they should always have been: notification tools that tell you to go and book, competing on how fast they alert you rather than on how much inventory they can seize. The illegitimate half of the market disappears and the legitimate half keeps operating. Regulators very rarely get to draw a line that clean.

If you want to see the shape of this without reading a specification, the ticket bot demo runs the same mechanic against event inventory, which is the commercial cousin of a consular calendar and has the advantage of being something you can click.

Does this work for people without good phones?

This objection is not a footnote. It is the whole design constraint, because the population this is meant to protect is precisely the population with the weakest devices and the worst connectivity. A control that helps affluent applicants and excludes everyone else has made the problem worse while appearing to solve it.

Three things follow. The booking device and the signing device must be allowed to differ, so that someone booking from a shared computer in an internet cafe can sign on their own handset. This is a companion device pairing, which is exactly what the presence flow is built to do, and it is a better fit here than a single device assumption would be.

The enrolment must not require a document upload, because the applicant is already handing documents to the consulate through the proper channel and duplicating that into a scheduling vendor creates a data liability for no benefit. We have made the general version of this argument in verifying an attribute without collecting an identity.

And there must be a staffed path, treated as a normal route rather than an exception, for the applicant with no smartphone at all. If that path is a grudging afterthought with a six week wait, the design has quietly reintroduced the same inequity through a different door.

Honest limits

Several, and they are real.

The agency has to adopt it, and agencies do not buy quickly. Consular scheduling is largely operated through outsourced vendors under multi year contracts, so the realistic entry point is those vendors and their contract renewals rather than a direct agency sale. Manav has no consular or motor vehicle agency deployments, and this post is a design argument, not a case study.

Capacity is the underlying problem and no identity control creates appointments. If demand is ten times supply, a perfectly fair queue is still a queue in which nine people out of ten fail. Presence binding changes who gets the slot and removes the broker's margin. It does not change how many slots exist. Anyone selling it as a fix for backlogs is misdescribing it.

A human for hire can still be present. An operator could employ people to sit and sign at release time on behalf of customers. This is meaningfully harder, because it does not scale the way a script does, it costs real wages per slot, and it cannot hoard inventory speculatively since the customer must be identified before the claim rather than after. But it is not impossible, and the counter check would pass only if that same person also attended, which for a visa interview it cannot.

The counter check needs integration. Verifying at the window means the clerk's terminal has to run the check, which is a separate piece of work from the booking system and often a separate contract. A booking side deployment alone still removes hoarding and resale, but the strongest form needs both ends.

Families and delegates need an explicit model. A parent books for a child, a spouse books for a partner, an employer books for a worker. These are legitimate and common. A design that treats every booking as strictly self service will break on contact with real families, so delegation has to be a first class feature with its own scope and expiry rather than a loophole.

What an agency or scheduling vendor can do this quarter

  1. Instrument the release. Publish, internally at first, how many slots were released and the distribution of time to claim. You cannot argue for a control you have not measured.
  2. Look at the claim latency histogram. Automated claiming shows up as a hard spike under two seconds that no population of humans produces. This is the cheapest diagnostic available and most agencies have never plotted it.
  3. Stop cancelling without a remedy path. If a booking is voided because a broker made it, the applicant needs a route back into the queue that does not put them at the end of it. Otherwise enforcement is a penalty on the victim.
  4. Write non transferability into the contract. Vendor agreements are renewed on a cycle. Add a requirement that bookings be bound to a claiming party and non transferable, and the procurement lever does work the engineering cannot.
  5. Pilot on one post and one appointment class. Presence bound claiming, one class, one location, measured against a comparable control site. A pilot with a comparison group is worth more than a national rollout with no baseline.
  6. Add the counter check to the pilot cohort only. This keeps the operational change small while producing the single most valuable data point, which is how many claimed slots are attended by a different person.
  7. Publish the fairness numbers. Release counts, claim latency, and attendance mismatch rates. Agencies rarely publish this and it is exactly the data that sustains political support for the fix.
  8. Fund the staffed path properly. Decide the target wait time for the non digital route before launch, and staff to it. Retrofitting this after complaints is how good designs acquire bad reputations.

Frequently asked questions

How do consulates stop bots from booking visa appointments? Today, mostly through challenge pages, rate limiting, account bans and periodic mass cancellation of bookings identified as automated. These are detection controls and they lose against operators who can afford solver services and residential proxies. The structural alternative is to require a presence signature from an enrolled human at the moment a slot is claimed, and to verify the same key at the counter, so slots cannot be hoarded or resold at all.

Why are there no visa appointment slots available? Two separate causes get conflated. The first is genuine capacity, since posts have finite interview hours and demand can exceed them by a wide margin. The second is that when slots are released in batches, automated claiming can drain a release before most people finish reading the calendar. Only the second is fixable with identity technology. Published wait time data from the issuing authority is the place to check which one you are facing.

Are visa slot booking services legal? It depends on the service and the jurisdiction. A tool that monitors availability and alerts you is quite different from an operation that claims slots under placeholder identities and resells them, and many schedulers prohibit the latter in their terms, which is the basis on which bookings get cancelled. Handing your account credentials to any third party is separately risky and often a terms violation on its own.

How is this different from just adding an account requirement? Accounts are farmed and lent. An account proves that someone knows a password, which is exactly the thing a broker can be given or can create in bulk. A presence signature proves that a specific enrolled human was there at the moment of claiming, and because the key stays on their device it cannot be transferred with the booking.

Does this mean collecting identity documents to book an appointment? No, and it should not. The applicant already provides documents to the agency through the application itself. The scheduler needs to know that one human claimed one slot and that the same human returns, which requires a key and a presence check, not a passport scan. Collecting identity twice creates a data liability without adding assurance.

Would this fix appointment backlogs? No. It changes who gets the available appointments and removes the broker's margin. It creates no additional capacity. An agency with a genuine shortfall still has a shortfall, and should say so rather than allow a fairness measure to be read as a capacity measure.

Sources

  1. US Embassy and Consulates in India, public consular announcements, including the March 2025 statement on cancelling appointments booked by bots: in.usembassy.gov
  2. US Department of State, visa appointment wait times and consular service information: travel.state.gov
  3. Cloudflare Turnstile, challenge based bot mitigation as deployed on public scheduling systems: cloudflare.com
  4. W3C, Web Authentication Level 3, the specification behind device bound signatures: w3.org
  5. NIST Special Publication 800-63 Digital Identity Guidelines, on authenticator assurance and restricted authenticators: pages.nist.gov
  6. Manav developer documentation, presence signatures and offline verifiable receipts: manav.id/docs
A queue is only fair if a place in it cannot be sold, and the way to make a place unsellable is to make it belong to a person rather than to a row in a table.