API Documentation
Access Python package download statistics programmatically. All endpoints return JSON unless otherwise noted; badges return SVG.
Base URL
All endpoint paths are relative to this base URL.
Authentication
JSON 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.
Rate Limits
Requests 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 |
| Team | 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 with429responses; the number of seconds until at least one token refills.
Errors
Errors 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"
}Project data
Public PyPI download statistics. Available to any plan with an API key.
Get project download statistics
Return the all-time download total and a per-version daily breakdown for the last 3 months. Optionally include PyPI metadata.
Endpoint
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. |
Notes
The 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 Request
curl -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"
}
}Response Status Codes
| Code | Description |
|---|---|
| 200 | Successful response |
| 401 | Missing or invalid API key |
| 404 | Project not found |
| 429 | Rate limit exceeded |
Search projects
Search PyPI projects by name. Results are ranked by total downloads.
Endpoint
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). |
Notes
Responses 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 Request
curl -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
}
]Response 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 |
Pro endpoints
Extended history and richer filters. Require an API key on a paid plan (Pro, Developer, or Team).
Get project downloads (Pro)
Daily per-version download counts over an extended history window, with CI traffic filtering.
Endpoint
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. |
Notes
Plan-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 |
| Team | 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 Request
curl -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
}
}
}Response 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 |
Badges
Embeddable SVG download badges for READMEs and project pages. Public — no API key, no rate limit. Cached for 12 hours.
Total downloads badge
SVG badge showing all-time downloads for a project.
Endpoint
Path Parameters
| Parameter | Type | Description |
|---|---|---|
project required | string | PyPI project name. Case-insensitive; normalized per PEP 503. |
Example Request
curl "https://api.pepy.tech/badge/requests" \
--output requests-total.svgResponse
Returns an SVG image of the total-downloads badge for the requested project.
Content-Type: image/svg+xml
Response Status Codes
| Code | Description |
|---|---|
| 200 | Successful response |
| 404 | Project not found |
Monthly downloads badge
SVG badge showing downloads in the last 30 days.
Endpoint
Path Parameters
| Parameter | Type | Description |
|---|---|---|
project required | string | PyPI project name. Case-insensitive; normalized per PEP 503. |
Example Request
curl "https://api.pepy.tech/badge/requests/month" \
--output requests-monthly.svgResponse
Returns an SVG image of the monthly-downloads badge.
Content-Type: image/svg+xml
Response Status Codes
| Code | Description |
|---|---|
| 200 | Successful response |
| 404 | Project not found |
Weekly downloads badge
SVG badge showing downloads in the last 7 days.
Endpoint
Path Parameters
| Parameter | Type | Description |
|---|---|---|
project required | string | PyPI project name. Case-insensitive; normalized per PEP 503. |
Example Request
curl "https://api.pepy.tech/badge/requests/week" \
--output requests-weekly.svgResponse
Returns an SVG image of the weekly-downloads badge.
Content-Type: image/svg+xml
Response Status Codes
| Code | Description |
|---|---|
| 200 | Successful response |
| 404 | Project not found |
Personalized badge
Customizable SVG badge — choose the period, number formatting, colors, and label text.
Endpoint
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. |
Notes
All 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 Request
curl "https://api.pepy.tech/personalized-badge/requests?period=month&units=international_system&left_color=grey&right_color=blue&left_text=Downloads"Response
Returns an SVG image of the customized downloads badge.
Content-Type: image/svg+xml
Response Status Codes
| Code | Description |
|---|---|
| 200 | Successful response |
| 400 | Invalid value for period, units, left_color, or right_color |
| 404 | Project not found |