GeezerVison is showing pepy.tech — pepy.tech API documentation Base URLhttps://api.pepy.tech All endpoint paths are relative to this base URL. AuthenticationAPI key in headerJSON API requests are authenticated with an API key sent in a request header. Badge endpoints (/badge/* and /personalized-badge/*) are public and require no key. X-API-Key: your_api_key Generate and manage keys on your user profile. Each account may have up to 3 active keys. Treat your API key like a password. Never commit it to a public repository or embed it in client-side code. Rate limitsPer API key, per minuteRequests are rate-limited per API key, in requests per minute (RPM). The active limit depends on the subscription plan attached to the key. | Plan | Sustained rate | Burst capacity |
|---|
| Free | 5 RPM | 10 requests | | Pro (preview) | 5 RPM | 10 requests | | Developer | 60 RPM | 120 requests | | Business | 300 RPM | 600 requests |
Every response includes rate-limit metadata: X-Rate-Limit-Remaining — tokens left in the current bucket.X-Rate-Limit-Retry-After-Seconds — sent with 429 responses; the number of seconds until at least one token refills. ErrorsJSON error bodyErrors return a non-2xx HTTP status and a JSON body with a single message field describing the problem. Per-endpoint status codes are listed in each section below. {
"message": "Project not found: requestz"
}
EndpointGET /api/v2/projects/{project} Path parameters| Parameter | Type | Description |
|---|
project Required | string | PyPI project name. Case-insensitive; normalized per PEP 503 (e.g. "Flask-Login" and "flask_login" both resolve to "flask-login"). |
Query parameters| Parameter | Type | Description |
|---|
includeMetadata Optional | boolean default: false | When true, the response includes a `metadata` object with PyPI-sourced details (summary, license, classifiers, latest version, etc.). Omitted otherwise. |
NotesThe daily breakdown window is fixed at the last 3 months. Use the Pro downloads endpoint for longer history. The metadata field is omitted when includeMetadata is false or when the project has no synced metadata yet. Example requestcurl -H "X-API-Key: $PEPY_API_KEY" \
"https://api.pepy.tech/api/v2/projects/requests?includeMetadata=true"
Response{
"id": "requests",
"total_downloads": 1395207458,
"versions": [
"2.31.0",
"2.32.0"
],
"downloads": {
"2024-05-12": {
"2.31.0": 1142321,
"2.32.0": 1231
},
"2024-05-13": {
"2.31.0": 1241242,
"2.32.0": 3234
}
},
"metadata": {
"summary": "Python HTTP for Humans.",
"description": "Requests is a simple, yet elegant, HTTP library.",
"license": "Apache-2.0",
"keywords": [
"http",
"requests"
],
"classifiers": [
"Programming Language :: Python :: 3"
],
"author": "Kenneth Reitz",
"author_email": "[email protected]",
"maintainer": null,
"maintainer_email": null,
"project_urls": {
"Homepage": "https://requests.readthedocs.io",
"Source": "https://github.com/psf/requests"
},
"home_page": "https://requests.readthedocs.io",
"download_url": null,
"requires_python": ">=3.8",
"requires_dist": [
"charset-normalizer<4,>=2",
"idna<4,>=2.5"
],
"latest_version": "2.32.0",
"latest_version_upload_time": "2024-05-20T16:32:11",
"metadata_synced_at": "2026-05-12T03:00:00"
}
}
Status codes| Code | Description |
|---|
| 200 | Successful response | | 401 | Missing or invalid API key | | 404 | Project not found | | 429 | Rate limit exceeded |
EndpointGET /api/v2/projects/search Query parameters| Parameter | Type | Description |
|---|
q Required | string | Search term matched against PyPI project names. Must be non-empty after trimming whitespace. | limit Optional | integer default: 20 | Maximum number of results to return. Results are ranked by total downloads (most downloaded first). |
NotesResponses are cached for 10 minutes at the edge. The 404 status does not apply to this endpoint — an empty search returns an empty array with a 200 status. Example requestcurl -H "X-API-Key: $PEPY_API_KEY" \
"https://api.pepy.tech/api/v2/projects/search?q=requests&limit=5"
Response[
{
"name": "requests",
"totalDownloads": 1395207458
},
{
"name": "requests-oauthlib",
"totalDownloads": 432101234
},
{
"name": "requests-toolbelt",
"totalDownloads": 211003456
}
]
Status codes| Code | Description |
|---|
| 200 | Successful response | | 400 | Missing or empty `q` parameter | | 401 | Missing or invalid API key | | 404 | Project not found | | 429 | Rate limit exceeded |
EndpointGET /service-api/v1/pro/projects/{project}/downloads Path parameters| Parameter | Type | Description |
|---|
project Required | string | PyPI project name. Case-insensitive; normalized per PEP 503. |
Query parameters| Parameter | Type | Description |
|---|
timeRange Optional | enum default: ONE_YEAR | How far back to return daily downloads. Allowed values: FOUR_MONTHS, THREE_MONTHS, ONE_YEAR, THREE_YEARS, FIVE_YEARS. The value is clamped to the maximum your plan permits — see Notes below. | includeCIDownloads Optional | boolean default: true | When false, downloads identified as coming from CI runners (GitHub Actions, GitLab CI, etc.) are excluded from the totals. Useful for measuring real user adoption. |
NotesPlan-based time range: The timeRange parameter is silently clamped to the maximum your plan allows. Requesting a longer range than your plan permits will not error — you will receive your plan's maximum window instead. | Plan | Maximum timeRange |
|---|
| Pro | ONE_YEAR | | Developer | THREE_YEARS | | Business | FIVE_YEARS |
CI filtering: When includeCIDownloads=false, downloads from known CI runners (GitHub Actions, GitLab CI, etc.) are excluded from each daily count. Use this to gauge real user adoption. Example requestcurl -H "X-API-Key: $PEPY_API_KEY" \
"https://api.pepy.tech/service-api/v1/pro/projects/requests/downloads?timeRange=ONE_YEAR&includeCIDownloads=false"
Response{
"downloads": {
"2024-05-12": {
"2.31.0": 1142321,
"2.32.0": 1231
},
"2024-05-13": {
"2.31.0": 1241242,
"2.32.0": 3234
}
}
}
Status codes| Code | Description |
|---|
| 200 | Successful response | | 401 | Missing or invalid API key | | 403 | API key belongs to a plan without Pro access | | 404 | Project not found | | 429 | Rate limit exceeded |
EndpointGET /badge/{project} Path parameters| Parameter | Type | Description |
|---|
project Required | string | PyPI project name. Case-insensitive; normalized per PEP 503. |
Example requestcurl "https://api.pepy.tech/badge/requests" \
--output requests-total.svg
ResponseReturns an SVG image of the total-downloads badge for the requested project. Content-Type: image/svg+xml Status codes| Code | Description |
|---|
| 200 | Successful response | | 404 | Project not found |
EndpointGET /badge/{project}/month Path parameters| Parameter | Type | Description |
|---|
project Required | string | PyPI project name. Case-insensitive; normalized per PEP 503. |
Example requestcurl "https://api.pepy.tech/badge/requests/month" \
--output requests-monthly.svg
ResponseReturns an SVG image of the monthly-downloads badge. Content-Type: image/svg+xml Status codes| Code | Description |
|---|
| 200 | Successful response | | 404 | Project not found |
EndpointGET /badge/{project}/week Path parameters| Parameter | Type | Description |
|---|
project Required | string | PyPI project name. Case-insensitive; normalized per PEP 503. |
Example requestcurl "https://api.pepy.tech/badge/requests/week" \
--output requests-weekly.svg
ResponseReturns an SVG image of the weekly-downloads badge. Content-Type: image/svg+xml Status codes| Code | Description |
|---|
| 200 | Successful response | | 404 | Project not found |
EndpointGET /personalized-badge/{project} Path parameters| Parameter | Type | Description |
|---|
project Required | string | PyPI project name. Case-insensitive; normalized per PEP 503. |
Query parameters| Parameter | Type | Description |
|---|
period Optional | enum default: MONTH | Time window to count. One of: WEEK, MONTH, TOTAL. (WEEKLY and MONTHLY are accepted as aliases for WEEK and MONTH.) | units Optional | enum default: INTERNATIONAL_SYSTEM | How to format the download number. INTERNATIONAL_SYSTEM = "1.2k", "3.4M". ABBREVIATION = "1.2K", "3.4M". NONE = raw integer with no abbreviation. | left_color Optional | enum default: BLACK | Color of the label (left side). One of: BLACK, BRIGHTGREEN, GREEN, YELLOWGREEN, RED, YELLOW, ORANGE, BLUE, GREY (or GRAY), LIGHTGREY, MAGENTA. Case-insensitive. | right_color Optional | enum default: GREEN | Color of the value (right side). Same allowed values as left_color. | left_text Optional | string default: downloads/month | Custom label text on the left side of the badge. Pass spaces as %20. |
NotesAll enum values are case-insensitive. Unknown values for period, units, left_color, or right_color return a 400 with a message identifying the invalid field. Example requestcurl "https://api.pepy.tech/personalized-badge/requests?period=month&units=international_system&left_color=grey&right_color=blue&left_text=Downloads"
ResponseReturns an SVG image of the customized downloads badge. Content-Type: image/svg+xml Status codes| Code | Description |
|---|
| 200 | Successful response | | 400 | Invalid value for period, units, left_color, or right_color | | 404 | Project not found |
|