---
title: "Exploring the CoWIN Vaccination API | Ameya Shenoy"
description: "Explore the CoWIN vaccination API with Ameya Shenoy’s 2021 notes on endpoints, booking requests, JWT authentication and implementation details for developers."
canonical: "https://www.codingcoffee.dev/blog/cowin-exploring-the-api"
published: "2021-06-15"
tags: "blog"
---

# CoWIN - Exploring the API

By Ameya Shenoy · Published 2021-06-15

Explore the CoWIN vaccination API with Ameya Shenoy’s 2021 notes on endpoints, booking requests, JWT authentication and implementation details for developers.

> Just to be fair this has not been tested. This is **not** the way I booked my slot for the vaccination.

**TL;DR**: You can probably automate vaccination slot booking

## Overview

CoWIN has made its APIs publicly available. Details about version 2 are documented on the [API Setu website](https://apisetu.gov.in/public/marketplace/api/cowin/cowin-protected-v2).

Most online discussions focused on notification services using the API to alert users of new slots. Services like [getjab](https://getjab.in/) and [VaccinateMe](https://www.vaccinateme.in) emerged alongside Telegram groups and PayTM's Vaccine Slot Finder tool.

However, these tools lacked actual booking automation. Given rapid slot availability depletion, I pursued automating the complete booking process upon slot detection.

## API Structure

The CoWIN system divides into [Public APIs](https://apisetu.gov.in/public/marketplace/api/cowin) and [Protected APIs](https://apisetu.gov.in/public/marketplace/api/cowin/cowin-protected-v2).

**Appointment Availability APIs** power notification features with both public and private endpoints:
- Public endpoint requires no authentication but returns cached data (up to 30 minutes old)
- Private endpoint requires authentication

The booking endpoint [/v2/appointment/schedule](https://apisetu.gov.in/public/marketplace/api/cowin/cowin-protected-v2#/Vaccination%20Appointment%20APIs/schedule) demands authentication via POST request.

## Booking Request Structure

```python
data = {
  "center_id": center_id,
  "session_id": session_id,
  "beneficiaries": [beneficiary],
  "slot": slot,
  "dose": 1
}
```

Parameters:
- **center_id**, **session_id**, **slot**: sourced from Appointment Availability API responses
- **dose**: either 1 or 2 depending on vaccination round
- **beneficiary**: extracted from decoded JWT Access Token

## Authentication & Headers

Repeated 403 Forbidden responses prompted header spoofing to simulate browser requests:

```python
headers = {
  'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:87.0) Gecko/20100101 Firefox/87.0',
  'Accept': 'application/json, text/plain, */*',
  'Accept-Language': 'en-US,en;q=0.5',
  'Origin': 'https://selfregistration.cowin.gov.in',
  'Authorization': f'Bearer {access_token}',
  'DNT': '1',
  'Connection': 'keep-alive',
  'Referer': 'https://selfregistration.cowin.gov.in/',
  'Sec-GPC': '1',
  'TE': 'Trailers',
}
```

## Obtaining JWT Access Token

1. Log into the [CoWIN self-registration portal](https://selfregistration.cowin.gov.in/) via desktop
2. Access browser Session Storage
3. Locate the **userToken** variable containing your JWT Access Token
4. Decode at [jwt.io](https://jwt.io/)

Decoded token contains:

```json
{
  "user_name": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "user_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "user_type": "BENEFICIARY",
  "mobile_number": "xxxxxxxxxx",
  "beneficiary_reference_id": "xxxxxxxxxxxxxx",
  "ua": "Mozilla/5.0 (X11; Linux x86_64; rv:87.0) Gecko/20100101 Firefox/87.0",
  "date_modified": "2021-05-05T14:32:15.194Z",
  "iat": "xxxxxxxxxx",
  "exp": "xxxxxxxxxx"
}
```

Use **beneficiary_reference_id** in booking requests and the full encoded token in authentication headers.

## Implementation

A proof-of-concept Python script automating slot discovery through booking is available in a [GitHub Gist](https://gist.github.com/codingCoffee/9ef47b80054291a1e236607339efc388). The code requires cleanup but functions as a demonstration.

## Observations & Speculations

- Frequent API hits result in IP-level bans; authenticated requests may also receive 403 responses, possibly indicating location-based restrictions
- User tokens expire after approximately 30 minutes, requiring re-authentication via OTP
- Despite API documentation claiming 100 requests per 5 minutes, practical thresholds appear significantly lower (approximately 10 requests/minute)
- GET Appointment Availability APIs work with or without authentication, possibly unintended
- POST methods require authentication, returning 401 Unauthorized without valid tokens
- User-Agent header spoofing appears essential to prevent 403 responses

---

Canonical page: https://www.codingcoffee.dev/blog/cowin-exploring-the-api

[Site guide](/llms.txt) · [Contact](/contact) · [Sitemap](/sitemap-index.xml)
