├── .prettierignore ├── assets ├── public-apis.png ├── scrapfly-dark-mode.svg ├── scrapfly-light-mode.svg └── shipped.svg ├── utils └── db │ ├── format-json.js │ ├── write-to-file.js │ ├── format-categories.js │ ├── separate-tables.js │ ├── group-row-content.js │ └── format-resources.js ├── .github ├── ISSUE_TEMPLATE.md ├── workflows │ ├── update-db.yml │ └── broken-link-checker.yml └── PULL_REQUEST_TEMPLATE.md ├── package.json ├── LICENSE ├── API.md ├── .lycheeignore ├── scripts └── db │ └── update-db.js ├── .gitignore ├── db └── categories.json └── CONTRIBUTING.md /.prettierignore: -------------------------------------------------------------------------------- 1 | README.md -------------------------------------------------------------------------------- /assets/public-apis.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timleland/public-apis/main/assets/public-apis.png -------------------------------------------------------------------------------- /utils/db/format-json.js: -------------------------------------------------------------------------------- 1 | module.exports = function (entries) { 2 | return `{\n"count": ${entries.length},\n"entries": ${JSON.stringify(entries, null, 4)}}` 3 | } 4 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Thanks for looking to open an issue for this project. 2 | 3 | If you are opening an issue to suggest adding a new entry, please consider opening a pull request instead! 4 | 5 | -------------------------------------------------------------------------------- /utils/db/write-to-file.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | 3 | module.exports = async function ({ data, filePath }) { 4 | await fs.writeFile(filePath, data, error => { 5 | if (error) { 6 | throw new Error(`Error writing to file: ${error}`) 7 | } 8 | }) 9 | 10 | return 11 | } 12 | -------------------------------------------------------------------------------- /utils/db/format-categories.js: -------------------------------------------------------------------------------- 1 | module.exports = function (categories) { 2 | return categories.map(category => ({ 3 | name: category, 4 | slug: category 5 | .trim() 6 | .toLowerCase() 7 | .replace(/&/g, 'and') 8 | .replace(/[^A-Z0-9/]+/gi, '-') 9 | .replace(/\s/g, '-'), 10 | })) 11 | } 12 | -------------------------------------------------------------------------------- /utils/db/separate-tables.js: -------------------------------------------------------------------------------- 1 | module.exports = function ({ readme, indexListIndex }) { 2 | return readme 3 | .map((child, i) => { 4 | if (i <= indexListIndex) return 5 | 6 | if (child.type === 'heading' && child.depth === 3) { 7 | const name = child.children[0].value 8 | const rows = readme[i + 1].children 9 | 10 | return { name, rows } 11 | } 12 | }) 13 | .filter(table => table) 14 | } 15 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "public-apis", 3 | "description": "A collaborative list of public APIs for developers", 4 | "scripts": { 5 | "update-db": "node scripts/db/update-db.js" 6 | }, 7 | "repository": { 8 | "type": "git", 9 | "url": "git+https://github.com/marcelscruz/public-apis.git" 10 | }, 11 | "license": "MIT", 12 | "homepage": "https://github.com/marcelscruz/public-apis#readme", 13 | "bugs": { 14 | "url": "https://github.com/marcelscruz/public-apis/issues" 15 | }, 16 | "dependencies": { 17 | "remark-parse": "^9.0.0", 18 | "unified": "^9.2.2" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /.github/workflows/update-db.yml: -------------------------------------------------------------------------------- 1 | name: Update DB 2 | 3 | on: 4 | push: { branches: main } 5 | # schedule: 6 | # # Every day at 00:00AM 7 | # - cron: '0 0 * * *' 8 | workflow_dispatch: 9 | 10 | jobs: 11 | update-db: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v3 15 | - uses: actions/setup-node@v3 16 | - run: npm install 17 | - run: npm run update-db 18 | - run: | 19 | git config user.name "GitHub Actions Bot" 20 | git config user.email "<>" 21 | - run: git add . 22 | - run: git commit -m "Auto updating db" || echo "Nothing to commit" 23 | - run: git push origin HEAD:main 24 | -------------------------------------------------------------------------------- /utils/db/group-row-content.js: -------------------------------------------------------------------------------- 1 | module.exports = function (tables) { 2 | return tables.map(({ name, rows }) => { 3 | const content = [] 4 | 5 | rows.forEach((child, i) => { 6 | if (i === 0) return // Table header 7 | 8 | if (child.type === 'link') { 9 | content.push({ 10 | link: child.url, 11 | name: child.children[0].value, 12 | description: '', 13 | }) 14 | } else { 15 | const lastContentItem = content.pop() 16 | content.push({ 17 | ...lastContentItem, 18 | description: `${lastContentItem.description} ${child.value}`, 19 | }) 20 | } 21 | }) 22 | 23 | return { name, rows: content } 24 | }) 25 | } 26 | -------------------------------------------------------------------------------- /utils/db/format-resources.js: -------------------------------------------------------------------------------- 1 | module.exports = function (tables) { 2 | return tables 3 | .map(({ name: categoryName, rows }) => { 4 | return rows.map(({ link, name: entryName, description: rawDescription }) => { 5 | const [description, auth, https, cors] = rawDescription 6 | .split('|') 7 | .map(item => item.trim()) 8 | .filter(item => item) 9 | 10 | return { 11 | API: entryName, 12 | Description: description, 13 | Auth: auth?.toLowerCase() === 'no' ? '' : auth, 14 | HTTPS: https?.toLowerCase() === 'yes' ? true : false, 15 | Cors: cors?.toLowerCase(), 16 | Link: link, 17 | Category: categoryName, 18 | } 19 | }) 20 | }) 21 | .flat() 22 | } 23 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | - [ ] My submission is formatted according to the guidelines in the [contributing guide](https://github.com/marcelscruz/public-apis/blob/main/CONTRIBUTING.md) 5 | - [ ] My addition is ordered alphabetically 6 | - [ ] My submission has a useful description 7 | - [ ] The description does not have more than 100 characters 8 | - [ ] The description does not end with punctuation 9 | - [ ] Each table column is padded with one space on either side 10 | - [ ] I have searched the repository for any relevant issues or pull requests 11 | - [ ] Any category I am creating has the minimum requirement of 3 items 12 | - [ ] All changes have been [squashed][squash-link] into a single commit 13 | 14 | [squash-link]: https://github.com/todotxt/todo.txt-android/wiki/Squash-All-Commits-Related-to-a-Single-Issue-into-a-Single-Commit 15 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Public APIs 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /API.md: -------------------------------------------------------------------------------- 1 | # API 2 | 3 | This repository auto-generates the `/db` folder after each commit to `main`. The folder includes two files: 4 | 5 | `categories.json` - A list of all categories 6 | 7 | `resources.json` - A list of all APIs 8 | 9 | You can then use [Octokit](https://github.com/octokit) to fetch the data from the `db` folder. 10 | 11 | Here's a minimal snippet on how to accomplish that: 12 | 13 | ```ts 14 | import { Octokit } from 'octokit' 15 | 16 | async function fetchResources(file: string) { 17 | const octokit = new Octokit({ auth: process.env.GITHUB_ACCESS_TOKEN }) 18 | 19 | const { data } = await octokit.rest.repos.getContent({ 20 | owner: 'marcelscruz', 21 | repo: 'public-apis', 22 | path: `/db/${file}.json`, 23 | }) 24 | 25 | if (data.download_url) { 26 | const result = await fetch(data.download_url) 27 | 28 | if (!result.ok) { 29 | throw new Error(`Unexpected response ${result.statusText}`) 30 | } 31 | 32 | return await result.json() 33 | } else { 34 | throw new Error('Download URL not found') 35 | } 36 | } 37 | ``` 38 | 39 | The response will be an object with the following structure: 40 | 41 | `categories.json`: 42 | 43 | ```ts 44 | { 45 | "count": number, 46 | "entries": [ 47 | { 48 | "name": string, 49 | "slug": string 50 | } 51 | ] 52 | } 53 | ``` 54 | 55 | `resources.json`: 56 | 57 | ```ts 58 | { 59 | "count": number, 60 | "entries": [ 61 | { 62 | "API": string, 63 | "Auth": string, 64 | "Category": string, 65 | "Cors": string, 66 | "Description": string, 67 | "HTTPS": boolean, 68 | "Link": string, 69 | } 70 | ] 71 | } 72 | ``` 73 | -------------------------------------------------------------------------------- /.lycheeignore: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | https://www.velib-metropole.fr/donnees-open-data-gbfs-du-service-velib-metropole 5 | https://www.damsuccess.com/hc/en-us/articles/202134055-REST-API 6 | https://www.hackerearth.com/docs/wiki/developers/v4 7 | https://www.digikey.com/en/resources/api-solutions 8 | http://geodb-cities-api.wirefreethought.com 9 | https://www.udemy.com/developers/instructor 10 | https://cheetaho.com/docs/getting-started 11 | https://collection.cooperhewitt.org/api 12 | https://www.infura.io/product/ethereum 13 | https://www.ups.com/upsdeveloperkit 14 | https://securitytrails.com/corp/api 15 | https://developer.uber.com/products 16 | https://www.discogs.com/developers 17 | https://opendata.city-adm.lviv.ua 18 | https://developers.printful.com 19 | https://www.fbi.gov/wanted/api 20 | https://www.saidit.net/dev/api 21 | https://developers.upwork.com 22 | https://jooble.org/api/about 23 | https://search.censys.io/api 24 | https://developers.bb.com.br 25 | https://api.squiggle.com.au 26 | https://www.pexels.com/api 27 | https://www.linguarobot.io 28 | https://api-docs.igdb.com 29 | https://www.geoplugin.com 30 | https://www.zenrows.com 31 | https://www.dati.gov.it 32 | https://docs.genius.com 33 | https://data.gov.sa/ar 34 | https://data.gov.cy 35 | https://www.tcgdex.net/docs 36 | https://nbaapi.com/graphql/ 37 | https://support.mywot.com/hc/en-us/sections/360004477734-API- 38 | https://oddsmagnet.com/oddsdata 39 | https://developers.aftership.com/reference/quick-start 40 | https://data.gov.sa/ 41 | https://tomba.io/api 42 | https://docs.aylien.com/textapi/#getting-started 43 | https://openai.com/index/openai-api 44 | https://www.sec.gov/search-filings/edgar-application-programming-interfaces 45 | https://datos.gob.ar/ 46 | https://www.drupal.org/drupalorg/docs/api 47 | https://api.imgbb.com/ 48 | -------------------------------------------------------------------------------- /scripts/db/update-db.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const remarkParse = require('remark-parse') 3 | const unified = require('unified') 4 | 5 | const formatCategories = require('../../utils/db/format-categories') 6 | const formatJson = require('../../utils/db/format-json') 7 | const formatResources = require('../../utils/db/format-resources') 8 | const groupRowContent = require('../../utils/db/group-row-content') 9 | const separateTables = require('../../utils/db/separate-tables') 10 | const writeToFile = require('../../utils/db/write-to-file') 11 | 12 | async function updateDB() { 13 | try { 14 | const readme = fs.readFileSync('./README.md', 'utf-8', (err, data) => { 15 | if (err) throw err 16 | readme = data 17 | }) 18 | 19 | const parsedReadme = unified().use(remarkParse).parse(readme).children 20 | const indexListIndex = parsedReadme.findIndex(child => child.type === 'list') 21 | 22 | // Create resources list 23 | const separatedTables = separateTables({ readme: parsedReadme, indexListIndex }) 24 | const tablesWithGroupedRowContent = groupRowContent(separatedTables) 25 | const formattedContent = formatResources(tablesWithGroupedRowContent) 26 | 27 | await writeToFile({ 28 | data: formatJson(formattedContent), 29 | filePath: './db/resources.json', 30 | }) 31 | 32 | // Create categories list 33 | const categories = parsedReadme[indexListIndex].children.map( 34 | category => category.children[0].children[0].children[0].value 35 | ) 36 | const categoriesList = formatCategories(categories) 37 | 38 | await writeToFile({ 39 | data: formatJson(categoriesList), 40 | filePath: './db/categories.json', 41 | }) 42 | } catch (error) { 43 | throw new Error('Error creating DB files:', error) 44 | } 45 | } 46 | 47 | updateDB() 48 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | pip-wheel-metadata/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | .pypirc 30 | 31 | # PyInstaller 32 | # Usually these files are written by a python script from a template 33 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 34 | *.manifest 35 | *.spec 36 | 37 | # Installer logs 38 | pip-log.txt 39 | pip-delete-this-directory.txt 40 | 41 | # Unit test / coverage reports 42 | htmlcov/ 43 | .tox/ 44 | .nox/ 45 | .coverage 46 | .coverage.* 47 | .cache 48 | nosetests.xml 49 | coverage.xml 50 | *.cover 51 | *.py,cover 52 | .hypothesis/ 53 | .pytest_cache/ 54 | 55 | # Translations 56 | *.mo 57 | *.pot 58 | 59 | # Django stuff: 60 | *.log 61 | local_settings.py 62 | db.sqlite3 63 | db.sqlite3-journal 64 | 65 | # Flask stuff: 66 | instance/ 67 | .webassets-cache 68 | 69 | # Scrapy stuff: 70 | .scrapy 71 | 72 | # Sphinx documentation 73 | docs/_build/ 74 | 75 | # PyBuilder 76 | target/ 77 | 78 | # Jupyter Notebook 79 | .ipynb_checkpoints 80 | 81 | # IPython 82 | profile_default/ 83 | ipython_config.py 84 | 85 | # pyenv 86 | .python-version 87 | 88 | # pipenv 89 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 90 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 91 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 92 | # install all needed dependencies. 93 | #Pipfile.lock 94 | 95 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 96 | __pypackages__/ 97 | 98 | # Celery stuff 99 | celerybeat-schedule 100 | celerybeat.pid 101 | 102 | # SageMath parsed files 103 | *.sage.py 104 | 105 | # Environments 106 | .env 107 | .venv 108 | env/ 109 | venv/ 110 | ENV/ 111 | env.bak/ 112 | venv.bak/ 113 | 114 | # Spyder project settings 115 | .spyderproject 116 | .spyproject 117 | 118 | # Rope project settings 119 | .ropeproject 120 | 121 | # mkdocs documentation 122 | /site 123 | 124 | # mypy 125 | .mypy_cache/ 126 | .dmypy.json 127 | dmypy.json 128 | 129 | # Pyre type checker 130 | .pyre/ 131 | 132 | # Node 133 | node_modules/ 134 | 135 | # VS Code Configs 136 | .vscode/ 137 | 138 | # Other 139 | .DS_Store -------------------------------------------------------------------------------- /.github/workflows/broken-link-checker.yml: -------------------------------------------------------------------------------- 1 | # This workflow uses the lychee-action to check the links 2 | # in your markdown files for validity. 3 | # You can exclude links via a .lycheeignore file in your repository root. 4 | # You find further information about lychee-action in the documentation at: 5 | # https://github.com/lycheeverse/lychee-action 6 | 7 | name: Check for broken links 8 | 9 | on: 10 | workflow_dispatch: 11 | schedule: # Run every weekday at 12:30 UTC 12 | - cron: '30 12 * * 1-5' 13 | 14 | jobs: 15 | Check-for-broken-links: 16 | runs-on: ubuntu-latest 17 | permissions: 18 | contents: read 19 | issues: write 20 | env: 21 | issue-lookup-label: automated-link-issue 22 | issue-content: ./lychee-out.md 23 | steps: 24 | - uses: actions/checkout@v4 25 | - name: Restore lychee cache 26 | uses: actions/cache@v4 27 | with: 28 | path: .lycheecache 29 | key: cache-lychee-${{ github.sha }} 30 | restore-keys: cache-lychee- 31 | - name: Link Checker 32 | id: lychee 33 | uses: lycheeverse/lychee-action@v1.10.0 34 | with: 35 | fail: false 36 | args: --verbose --no-progress --exclude-file .lycheeignore '**/*.md' 37 | output: ${{ env.issue-content }} 38 | 39 | # Permissions (issues: read) 40 | - name: 'Look for an existing issue' 41 | if: ${{ failure() }} 42 | id: last-issue 43 | uses: micalevisk/last-issue-action@v2 44 | # Find the last updated open issue with a `automated-issue` label: 45 | with: 46 | state: open 47 | labels: ${{ env.issue-lookup-label }} 48 | 49 | # Permissions (issues: write) 50 | - name: 'Create a new issue, or update an existing one' 51 | if: ${{ failure() }} 52 | uses: peter-evans/create-issue-from-file@v4 53 | with: 54 | title: 'docs: Broken links found' 55 | content-filepath: ${{ env.issue-content }} 56 | # Update an existing issue if one was found (issue_number), 57 | # otherwise an empty value creates a new issue: 58 | issue-number: ${{ steps['last-issue']['outputs']['issue-number'] }} 59 | # Add a label(s) that `last-issue` can use to find this issue, 60 | # and any other relevant labels for the issue itself: 61 | labels: | 62 | ${{ env.issue-lookup-label }} 63 | broken-link, docs 64 | -------------------------------------------------------------------------------- /db/categories.json: -------------------------------------------------------------------------------- 1 | { 2 | "count": 52, 3 | "entries": [ 4 | { 5 | "name": "Animals", 6 | "slug": "animals" 7 | }, 8 | { 9 | "name": "Anime", 10 | "slug": "anime" 11 | }, 12 | { 13 | "name": "Anti-Malware", 14 | "slug": "anti-malware" 15 | }, 16 | { 17 | "name": "Art & Design", 18 | "slug": "art-and-design" 19 | }, 20 | { 21 | "name": "Authentication & Authorization", 22 | "slug": "authentication-and-authorization" 23 | }, 24 | { 25 | "name": "Blockchain", 26 | "slug": "blockchain" 27 | }, 28 | { 29 | "name": "Books", 30 | "slug": "books" 31 | }, 32 | { 33 | "name": "Business", 34 | "slug": "business" 35 | }, 36 | { 37 | "name": "Calendar", 38 | "slug": "calendar" 39 | }, 40 | { 41 | "name": "Cloud Storage & File Sharing", 42 | "slug": "cloud-storage-and-file-sharing" 43 | }, 44 | { 45 | "name": "Continuous Integration", 46 | "slug": "continuous-integration" 47 | }, 48 | { 49 | "name": "Cryptocurrency", 50 | "slug": "cryptocurrency" 51 | }, 52 | { 53 | "name": "Currency Exchange", 54 | "slug": "currency-exchange" 55 | }, 56 | { 57 | "name": "Data Validation", 58 | "slug": "data-validation" 59 | }, 60 | { 61 | "name": "Development", 62 | "slug": "development" 63 | }, 64 | { 65 | "name": "Dictionaries", 66 | "slug": "dictionaries" 67 | }, 68 | { 69 | "name": "Documents & Productivity", 70 | "slug": "documents-and-productivity" 71 | }, 72 | { 73 | "name": "Email", 74 | "slug": "email" 75 | }, 76 | { 77 | "name": "Entertainment", 78 | "slug": "entertainment" 79 | }, 80 | { 81 | "name": "Environment", 82 | "slug": "environment" 83 | }, 84 | { 85 | "name": "Events", 86 | "slug": "events" 87 | }, 88 | { 89 | "name": "Finance", 90 | "slug": "finance" 91 | }, 92 | { 93 | "name": "Food & Drink", 94 | "slug": "food-and-drink" 95 | }, 96 | { 97 | "name": "Games & Comics", 98 | "slug": "games-and-comics" 99 | }, 100 | { 101 | "name": "Geocoding", 102 | "slug": "geocoding" 103 | }, 104 | { 105 | "name": "Government", 106 | "slug": "government" 107 | }, 108 | { 109 | "name": "Health", 110 | "slug": "health" 111 | }, 112 | { 113 | "name": "Jobs", 114 | "slug": "jobs" 115 | }, 116 | { 117 | "name": "Machine Learning", 118 | "slug": "machine-learning" 119 | }, 120 | { 121 | "name": "Music", 122 | "slug": "music" 123 | }, 124 | { 125 | "name": "News", 126 | "slug": "news" 127 | }, 128 | { 129 | "name": "Open Data", 130 | "slug": "open-data" 131 | }, 132 | { 133 | "name": "Open Source Projects", 134 | "slug": "open-source-projects" 135 | }, 136 | { 137 | "name": "Patent", 138 | "slug": "patent" 139 | }, 140 | { 141 | "name": "Personality", 142 | "slug": "personality" 143 | }, 144 | { 145 | "name": "Phone", 146 | "slug": "phone" 147 | }, 148 | { 149 | "name": "Photography", 150 | "slug": "photography" 151 | }, 152 | { 153 | "name": "Podcasts", 154 | "slug": "podcasts" 155 | }, 156 | { 157 | "name": "Programming", 158 | "slug": "programming" 159 | }, 160 | { 161 | "name": "Science & Math", 162 | "slug": "science-and-math" 163 | }, 164 | { 165 | "name": "Security", 166 | "slug": "security" 167 | }, 168 | { 169 | "name": "Shopping", 170 | "slug": "shopping" 171 | }, 172 | { 173 | "name": "Social", 174 | "slug": "social" 175 | }, 176 | { 177 | "name": "Sports & Fitness", 178 | "slug": "sports-and-fitness" 179 | }, 180 | { 181 | "name": "Test Data", 182 | "slug": "test-data" 183 | }, 184 | { 185 | "name": "Text Analysis", 186 | "slug": "text-analysis" 187 | }, 188 | { 189 | "name": "Tracking", 190 | "slug": "tracking" 191 | }, 192 | { 193 | "name": "Transportation", 194 | "slug": "transportation" 195 | }, 196 | { 197 | "name": "URL Shorteners", 198 | "slug": "url-shorteners" 199 | }, 200 | { 201 | "name": "Vehicle", 202 | "slug": "vehicle" 203 | }, 204 | { 205 | "name": "Video", 206 | "slug": "video" 207 | }, 208 | { 209 | "name": "Weather", 210 | "slug": "weather" 211 | } 212 | ]} -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to public-apis 2 | 3 | > ❗️ The `/db` folder is auto-generated, so please **_do not_** edit it. Changes related to public APIs should happen on the `README.md` file. 4 | 5 | > While the masses of pull requests and community involvement are appreciated, some pull requests have been specifically 6 | > opened to market company APIs that offer paid solutions. This API list is not a marketing tool, but a tool to help the 7 | > community build applications and use free, public APIs quickly and easily. Pull requests that are identified as marketing attempts will not be accepted. 8 | > 9 | > Please make sure the API you want to add has full, free access or at least a free tier and does not depend on the purchase of a device/service before submitting. An example that would be rejected is an API that is used to control a smart outlet - the API is free, but you must purchase the smart device. 10 | > 11 | > Thanks for understanding! :) 12 | 13 | ## Formatting 14 | 15 | Current API entry format: 16 | 17 | | API | Description | Auth | HTTPS | CORS | 18 | | ------------------------------------ | ------------------ | ---------------------------------------- | --------------------------- | --------------------------------------------------------------------------------------- | 19 | | API Title(Link to API documentation) | Description of API | Does this API require authentication? \* | Does the API support HTTPS? | Does the API support [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)? \* | 20 | 21 | Example entry: 22 | 23 | ``` 24 | | [NASA](https://api.nasa.gov) | NASA data, including imagery | No | Yes | Yes | 25 | ``` 26 | 27 | The URL must start with `http://` or `https://`. 28 | 29 | Currently, the only accepted inputs for the `Auth` field are as follows: 30 | 31 | - `OAuth` - _the API supports OAuth_ 32 | - `apiKey` - _the API uses a private key string/token for authentication - try and use the correct parameter_ 33 | - `X-Mashape-Key` - _the name of the header which may need to be sent_ 34 | - `No` - _the API requires no authentication to run_ 35 | - `User-Agent` - _the name of the header to be sent with requests to the API_ 36 | 37 | Currently, the only accepted inputs for the `CORS` field are as follows: 38 | 39 | - `Yes` - _the API supports CORS_ 40 | - `No` - _the API does not support CORS_ 41 | - `Unknown` - _it is unknown if the API supports CORS_ 42 | 43 | _Without proper [CORS configuration](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) an API will only be usable server side._ 44 | 45 | After you've created a branch on your fork with your changes, it's time to [make a pull request][pr-link]. 46 | 47 | _Please follow the guidelines given below while making a Pull Request to the Public APIs_ 48 | 49 | ## Pull Request Guidelines 50 | 51 | - Never put an update/new version of an API that is already listed, the old version of the API gets deprecated. 52 | - Continue to follow the alphabetical ordering that is in place per section. 53 | - Each table column should be padded with one space on either side. 54 | - The Description should not exceed 100 characters. 55 | - If an API seems to fall into multiple categories, please place the listing within the section most in line with the services offered through the API. For example, the Instagram API is listed under `Social` since it is mainly a social network, even though it could also apply to `Photography`. 56 | - Add one link per Pull Request. 57 | - Make sure the PR title is in the format of `Add Api-name API` _for e.g._: `Add Blockchain API` 58 | - Use a short descriptive commit message. _for e.g._: ❌`Update Readme.md` ✔ `Add Blockchain API to Cryptocurrency` 59 | - Search previous Pull Requests or Issues before making a new one, as yours may be a duplicate. 60 | - Don't mention the TLD(Top Level Domain) in the name of the API. _for e.g._: ❌Gmail.com ✔Gmail 61 | - Please make sure the API name does not end with `API`. _for e.g._: ❌Gmail API ✔Gmail 62 | - Please make sure the API has proper documentation. 63 | - Please make sure you squash all commits together before opening a pull request. If your pull request requires changes upon review, please be sure to squash all additional commits as well. [This wiki page][squash-link] outlines the squash process. 64 | - Target your Pull Request to the `main` branch of the `public-apis` 65 | 66 | Once you’ve submitted a pull request, the collaborators can review your proposed changes and decide whether or not to incorporate (pull in) your changes. 67 | 68 | ### Pull Request Pro Tips 69 | 70 | - [Fork][fork-link] the repository and [clone][clone-link] it locally. 71 | Connect your local repository to the original `upstream` repository by adding it as a [remote][remote-link]. 72 | Pull in changes from `upstream` often so that you stay up to date and so when you submit your pull request, 73 | merge conflicts will be less likely. See more detailed instructions [here][syncing-link]. 74 | - Create a [branch][branch-link] for your edits. 75 | - Contribute in the style of the project as outlined above. This makes it easier for the collaborators to merge 76 | and for others to understand and maintain in the future. 77 | 78 | ### Open Pull Requests 79 | 80 | Once you’ve opened a pull request, a discussion will start around your proposed changes. 81 | 82 | Other contributors and users may chime in, but ultimately the decision is made by the collaborators. 83 | 84 | During the discussion, you may be asked to make some changes to your pull request. 85 | 86 | If so, add more commits to your branch and push them – they will automatically go into the existing pull request. But don't forget to squash them. 87 | 88 | Opening a pull request will trigger a build to check the validity of all links in the project. After the build completes, **please ensure that the build has passed**. If the build did not pass, please view the build logs and correct any errors that were found in your contribution. 89 | 90 | _Thanks for being a part of this project, and we look forward to hearing from you soon!_ 91 | 92 | [branch-link]: http://guides.github.com/introduction/flow/ 93 | [clone-link]: https://help.github.com/articles/cloning-a-repository/ 94 | [fork-link]: http://guides.github.com/activities/forking/ 95 | [oauth-link]: https://en.wikipedia.org/wiki/OAuth 96 | [pr-link]: https://help.github.com/articles/creating-a-pull-request/ 97 | [remote-link]: https://help.github.com/articles/configuring-a-remote-for-a-fork/ 98 | [syncing-link]: https://help.github.com/articles/syncing-a-fork 99 | [squash-link]: https://github.com/todotxt/todo.txt-android/wiki/Squash-All-Commits-Related-to-a-Single-Issue-into-a-Single-Commit 100 | -------------------------------------------------------------------------------- /assets/scrapfly-dark-mode.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /assets/scrapfly-light-mode.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /assets/shipped.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | --------------------------------------------------------------------------------