API Reference
X-Bypass-Token to override these limits, please make an issue on the GitHub repository explaining your specific use case.
OSMA exposes two REST APIs — one for the NPM package dataset, one for PyPI. Both are identical in structure. All endpoints return JSON and support cross-origin requests (CORS open). No authentication required.
Base URLs
NPM API
PyPI API
Lightweight endpoint for UptimeRobot or health monitors. Does not query the database. Always responds instantly.
Example Request
curl https://notamitgamer-osma-npm-api.hf.space/ping
Example Response
"ping": "pong"
}
Returns 200 OK with package count when the database is ready. Returns 503 if the database is still initializing after a cold start.
Example Request
Example Response
"status": "ok",
"total_packages": 3881465
}
Returns total package count plus metadata about the dataset source and snapshot nature. Intended for display in dashboard stats bars.
Example Request
Example Response
"total_npm_packages": 3881465,
"source": "npmjs.com",
"note": "Snapshot dataset — updated periodically."
}
Returns packages in stable order by package_no. Use page and limit to paginate through the full dataset.
Parameters
| Parameter | Type | Default | Max | Required | Description |
|---|---|---|---|---|---|
| page | integer | 1 | — | optional | Page number, 1-indexed |
| limit | integer | 200 | 500 | optional | Rows per page |
Example Request
Example Response
"page": 1,
"limit": 5,
"results": [
{ "no": 1, "name": "--123hoodmane-pyodide", "version": "latest", "url": "https://www.npmjs.com/package/..." },
...
]
}
page
limit (max 500)
Searches package names and returns results ranked by match quality: exact match first (rank 0), starts-with second (rank 1), contains last (rank 2). Results are sorted by rank then alphabetically within each rank.
Parameters
| Parameter | Type | Default | Max | Required | Description |
|---|---|---|---|---|---|
| q | string | — | 100 chars | required | Search query. Min 2 characters. |
| limit | integer | 250 | 500 | optional | Max results to return |
Example Request
Example Response
"query": "react",
"count": 250,
"results": [
{ "no": 42, "name": "react", "version": "18.3.1", "url": "...", "rank": 0 },
{ "no": 88, "name": "react-dom", "version": "18.3.1", "url": "...", "rank": 1 },
...
]
}
q (min 2 chars)
limit (max 500)
Lightweight endpoint for UptimeRobot or health monitors. Does not query the database. Always responds instantly.
Example Request
Example Response
Returns 200 OK with package count when database is ready. Returns 503 during cold start initialization.
Example Request
Example Response
"status": "ok",
"total_packages": 780432
}
Returns total package count and dataset source metadata.
Example Request
Example Response
"total_pypi_packages": 780432,
"source": "pypi.org",
"note": "Snapshot dataset — updated periodically."
}
Returns packages in stable order by package_no. Paginate using page and limit.
Parameters
| Parameter | Type | Default | Max | Required | Description |
|---|---|---|---|---|---|
| page | integer | 1 | — | optional | Page number, 1-indexed |
| limit | integer | 200 | 500 | optional | Rows per page |
Example Request
Example Response
"page": 1,
"limit": 5,
"results": [
{ "no": 1, "name": "0", "version": "0.1.0", "url": "https://pypi.org/project/0/" },
...
]
}
page
limit (max 500)
Searches package names and returns results ranked by match quality. Rank 0 = exact, 1 = starts-with, 2 = contains.
Parameters
| Parameter | Type | Default | Max | Required | Description |
|---|---|---|---|---|---|
| q | string | — | 100 chars | required | Search query. Min 2 characters. |
| limit | integer | 250 | 500 | optional | Max results to return |
Example Request
Example Response
"query": "requests",
"count": 87,
"results": [
{ "no": 512, "name": "requests", "version": "2.31.0", "url": "...", "rank": 0 },
...
]
}
q (min 2 chars)
limit (max 500)
Returns the actual IP address that the API proxy recorded for your request, along with the parsed headers. Helpful for troubleshooting rate limit blocks across networks.
Example Request
Issues a cryptographically signed bypass token that allows you to skip all rate limits for 1 hour. This endpoint requires the correct secret parameter. Include the returned token in subsequent requests as the X-Bypass-Token header.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| secret | string | required | The developer bypass secret. |
Example Request
Example Response
"bypass_token": "1714420000:a1b2c3d4...",
"valid_for_seconds": 3600,
"usage": "Send as header: X-Bypass-Token:
}
Forces the server to re-download the latest CSV dataset from HuggingFace and rebuild the SQLite database in the background. Requires the secret parameter. Responses with 503 while rebuilding.
Limits & Notes
APIs are strictly rate-limited to 10 requests per minute and 100 requests per hour per IP to protect the free-tier infrastructure. Send the X-Bypass-Token header to override this.
Both datasets are snapshots. NPM frozen 2026-04-29 09:42 IST. PyPI frozen 2026-04-29 08:45 IST. Packages published after these dates are not indexed.
Both APIs have Access-Control-Allow-Origin: *. You can call them directly from any browser-based frontend with no proxy needed.
On first boot after a deployment, each server downloads its dataset and builds a SQLite index (~1 min). The /health endpoint returns 503 during this window. UptimeRobot prevents this in normal operation.
Response Schema
When querying the /browse or /search endpoints, the returned results array contains objects with the following fields:
| Field | Type | Description |
|---|---|---|
| no | integer | The stable, sequential ID/rank of the package within the snapshot database. |
| name | string | The exact, registered name of the package. |
| version | string | The version string available at the time the snapshot was taken. |
| url | string | The absolute link to the package on the official registry website. |
| rank | integer | (Only in /search) The match quality. 0 = Exact match, 1 = Starts with query, 2 = Contains query. |
Common Errors
Why it happens: The API URL path is incorrect or misspelled (e.g., trying to access /searc instead of /search).
Why it happens: You called the /search endpoint without providing the required q query parameter, or the search query was less than 2 characters long.
Why it happens: You exceeded the 10/min or 100/hour rate limit block. The JSON response will include an error string, and the HTTP headers will include a Retry-After value indicating how many seconds you need to wait before making another request.
Why it happens: The server was asleep and is experiencing a "Cold Start". It is currently downloading the multi-gigabyte dataset and building the in-memory SQLite index. This is completely normal on free-tier hosting and usually resolves within 1 minute. Please wait and try your request again.
500 Internal Server Errors or found a bug, please open an issue on GitHub or contact me directly at mail@amit.is-a.dev.
Frequently Asked Questions
X-Bypass-Token.
Access-Control-Allow-Origin: *), meaning browser-based frontend applications can fetch data directly without encountering CORS blocking.
0 means the query exactly matches the package name. 1 means the package name starts with the query. 2 means the package name contains the query somewhere inside it.
/stats endpoint for the exact, live metadata.