Every API here is available over the APIs.io API and to AI agents over MCP.
MCP server
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
Tools for apis
7 MCP tools reach this
find_apisBrowse and filter every API in the catalog.
get_api_artifactsOne API's artifacts, grouped by type.
get_openapiThe primary OpenAPI for this API.
find_similar_apisAPIs that look like this one.
apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
resolveTurn a domain, URL or GitHub org into the provider it belongs to.
find_cohortsEvery scored population of providers in the catalog.
All 92 tools →
Call it yourself
curl for this page
This API
curl "https://apis.io/api/v1/apis/honesthook:honesthook-github-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"
Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.
Get an API key
Free tier, no form to fill in. Signing in shares your email address with us — we
store it to create your key and to recognise you if you sign in with another
provider. See our Privacy Policy and
Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: HonestHook GitHub API
version: 1.0.0
description: Profiles and posts from the major social networks, through one API. One key, one response shape; rate limits, retries and platform changes are on us. Clean JSON for your app or your AI agent. We read the exact field each platform publishes, and return null when none exists. Plus a historical trend archive that answers what was trending, which cannot be reconstructed after the fact.
contact:
url: https://honesthook.com
license:
name: Proprietary
url: https://honesthook.com/docs
servers:
- url: https://honesthook.com
security:
- bearerAuth: []
tags:
- name: Github
paths:
/api/v1/github/profile:
get:
operationId: githubProfile
summary: Public profile on github, with the exact follower count
x-credits: 1
x-charges-without-result: false
description: 'One public profile, normalised into the same envelope as every other platform. Source: api.github.com (official, authenticated). Costs 1 credit; the answer is cached for an hour and a cache hit costs nothing (`cached: true`, `credits_used: 0`).
GitHub username: letters, digits and single hyphens, up to 39 characters, not starting or ending with a hyphen.'
parameters:
- name: handle
in: query
required: true
description: 'GitHub username: letters, digits and single hyphens, up to 39 characters, not starting or ending with a hyphen.'
schema:
type: string
pattern: ^[A-Za-z0-9](?:[A-Za-z0-9]|-(?=[A-Za-z0-9])){0,38}$
example: torvalds
responses:
'200':
description: Profile found
content:
application/json:
schema:
$ref: '#/components/schemas/ProfileEnvelope'
'400':
description: '`parametro_invalido` — the handle is missing or does not match this platform''s format. Nothing is charged.'
content:
application/json:
schema:
$ref: '#/components/schemas/ProfileEnvelope'
'401':
description: '`chave_invalida` — key missing, unknown or inactive.'
content:
application/json:
schema:
$ref: '#/components/schemas/ProfileEnvelope'
'402':
description: 'Out of credits. Two different types, and they mean different things: `sem_creditos` (both wallets are empty) and `teto_estourado` (the key has a monthly ceiling and hit it). Waiting does not help either one before the 1st — this is not a rate limit.'
content:
application/json:
schema:
$ref: '#/components/schemas/ProfileEnvelope'
'404':
description: '`nao_encontrado` — no such profile on that platform.'
content:
application/json:
schema:
$ref: '#/components/schemas/ProfileEnvelope'
'451':
description: '`bloqueado` — the platform refused us. The resource exists and YOUR key is fine; 403 would wrongly blame the caller.'
content:
application/json:
schema:
$ref: '#/components/schemas/ProfileEnvelope'
'503':
description: '`indisponivel` — this endpoint is switched off in the catalogue, or a dependency of ours is down. Your key is fine.'
content:
application/json:
schema:
$ref: '#/components/schemas/ProfileEnvelope'
tags:
- Github
/api/v1/github/repos:
get:
operationId: githubRepos
summary: Public repositories of a GitHub account, with stars and forks
description: 'Repositorios publicos de um usuario do GitHub, via API oficial. Campos com o NOME DA FONTE: stargazers_count, forks_count, open_issues_count, watchers_count, language, topics, license (SPDX), archived, fork, created_at, updated_at, pushed_at. Repositorio NAO e post: nada aqui vira metrics, e estrela nao e like. Conta sem repositorio responde items vazio e e cobrada; conta inexistente nao.'
x-creditos: 1
parameters:
- name: handle
in: query
required: true
schema:
type: string
- name: limit
in: query
required: false
schema:
type: integer
responses:
'200':
description: Data found.
'400':
description: See the shared error shape.
'401':
description: See the shared error shape.
'402':
description: See the shared error shape.
'404':
description: See the shared error shape.
'405':
description: See the shared error shape.
'451':
description: See the shared error shape.
'502':
description: See the shared error shape.
'503':
description: See the shared error shape.
tags:
- Github
/api/v1/github/repo:
get:
operationId: githubRepo
summary: One public GitHub repository, with the source's own field names — stars, forks…
description: 'One public GitHub repository. Fields keep the SOURCE names -- stargazers_count, forks_count, open_issues_count, watchers_count, language, topics, archived, fork -- because a repository is not a post and a star is not a like. WARNING: watchers_count equals stargazers_count in the API; real watchers are in subscribers_count, which this endpoint does not return. A renamed repository answers 200 under its NEW name: we compare full_name with what you asked and give 404 if they differ, instead of serving the redirect silently.'
x-creditos: 1
parameters:
- name: repo
in: query
required: true
schema:
type: string
responses:
'200':
description: Data found.
'400':
description: See the shared error shape.
'401':
description: See the shared error shape.
'402':
description: See the shared error shape.
'404':
description: See the shared error shape.
'405':
description: See the shared error shape.
'451':
description: See the shared error shape.
'502':
description: See the shared error shape.
'503':
description: See the shared error shape.
tags:
- Github
/api/v1/github/repo/issues:
get:
operationId: githubRepoIssues
summary: The issues of a GitHub repository AND its pull requests, which the API counts…
description: 'The issues of a GitHub repository AND its pull requests. The GitHub API counts every PR as an issue: MEASURED, 8 of the 10 items it returned were PRs. Each item carries is_pull_request (from the presence of the pull_request key) and a url that reads /pull/N or /issues/N. We do NOT filter the PRs out -- hiding 8 of 10 items would surprise more than labelling them. state=all, so closed issues come too.'
x-creditos: 1
parameters:
- name: repo
in: query
required: true
schema:
type: string
- name: limit
in: query
required: false
schema:
type: integer
responses:
'200':
description: Data found.
'400':
description: See the shared error shape.
'401':
description: See the shared error shape.
'402':
description: See the shared error shape.
'404':
description: See the shared error shape.
'405':
description: See the shared error shape.
'451':
description: See the shared error shape.
'502':
description: See the shared error shape.
'503':
description: See the shared error shape.
tags:
- Github
/api/v1/github/repo/readme:
get:
operationId: githubRepoReadme
summary: The README of a GitHub repository, decoded from the base64 the API returns
description: The README of a GitHub repository, DECODED from the base64 the API returns. The endpoint resolves which file is the README (readme.md, README, .github/README.md) and the answer says which one it was, in name and path. If the API declares an encoding other than base64 -- which it does for large files -- content is null and encoding comes through as it arrived, instead of an empty string served as a README.
x-creditos: 1
parameters:
- name: repo
in: query
required: true
schema:
type: string
responses:
'200':
description: Data found.
'400':
description: See the shared error shape.
'401':
description: See the shared error shape.
'402':
description: See the shared error shape.
'404':
description: See the shared error shape.
'405':
description: See the shared error shape.
'451':
description: See the shared error shape.
'502':
description: See the shared error shape.
'503':
description: See the shared error shape.
tags:
- Github
/api/v1/github/repo/releases:
get:
operationId: githubRepoReleases
summary: The releases of a GitHub repository, each saying whether it is a prerelease…
description: 'The releases of a GitHub repository. Every item says prerelease and draft, and that is not decoration: MEASURED, seven of ten were prereleases and the most recent one was a canary. assets is the COUNT of attached files, not the files. reactions keeps the GitHub names, and total_count is NOT likes -- measured, a release with total_count 3 had one +1 and two hooray.'
x-creditos: 1
parameters:
- name: repo
in: query
required: true
schema:
type: string
- name: limit
in: query
required: false
schema:
type: integer
responses:
'200':
description: Data found.
'400':
description: See the shared error shape.
'401':
description: See the shared error shape.
'402':
description: See the shared error shape.
'404':
description: See the shared error shape.
'405':
description: See the shared error shape.
'451':
description: See the shared error shape.
'502':
description: See the shared error shape.
'503':
description: See the shared error shape.
tags:
- Github
/api/v1/github/issue:
get:
operationId: githubIssue
summary: One GitHub issue or pull request by number — the same path serves both, and the…
description: 'One GitHub issue OR pull request by number -- the same API path serves both and there is no issue-only endpoint. The item says which, through is_pull_request and through the url. number is REQUIRED and has no default: there is no such thing as a default issue, and guessing 1 would serve the wrong one with a 200.'
x-creditos: 1
parameters:
- name: repo
in: query
required: true
schema:
type: string
- name: number
in: query
required: true
schema:
type: string
responses:
'200':
description: Data found.
'400':
description: See the shared error shape.
'401':
description: See the shared error shape.
'402':
description: See the shared error shape.
'404':
description: See the shared error shape.
'405':
description: See the shared error shape.
'451':
description: See the shared error shape.
'502':
description: See the shared error shape.
'503':
description: See the shared error shape.
tags:
- Github
/api/v1/github/issue/comments:
get:
operationId: githubIssueComments
summary: The conversation comments on a GitHub issue or pull request — text, date and…
description: 'The conversation comments on a GitHub issue or pull request: text, dates and reactions. WHO WROTE EACH ONE IS NOT RETURNED -- login, avatar and profile url arrive in the response and are discarded, and so is author_association, which is an attribute of the person. Code REVIEW comments on a PR live at another endpoint and are not here. An empty list is an answer; an issue that does not exist is a real 404.'
x-creditos: 1
parameters:
- name: repo
in: query
required: true
schema:
type: string
- name: number
in: query
required: true
schema:
type: string
responses:
'200':
description: Data found.
'400':
description: See the shared error shape.
'401':
description: See the shared error shape.
'402':
description: See the shared error shape.
'404':
description: See the shared error shape.
'405':
description: See the shared error shape.
'451':
description: See the shared error shape.
'502':
description: See the shared error shape.
'503':
description: See the shared error shape.
tags:
- Github
components:
schemas:
ProfileEnvelope:
type: object
required:
- success
- platform
- endpoint
- data
- error
- credits_used
- credits_remaining
- cached
- request_id
description: Identical shape on success and on error, so a client writes one parser. `success` is the only field that decides; `data` and `error` are mutually exclusive and the other is null, never absent.
properties:
success:
type: boolean
platform:
type: string
endpoint:
type: string
data:
type:
- object
- 'null'
properties:
author:
$ref: '#/components/schemas/Author'
items:
type: array
items:
type: object
has_more:
type:
- boolean
- 'null'
next_cursor:
type:
- string
- 'null'
error:
type:
- object
- 'null'
properties:
type:
type: string
enum:
- parametro_invalido
- chave_invalida
- sem_creditos
- teto_estourado
- nao_encontrado
- bloqueado
- indisponivel
description: Branch on this, never on the message text.
message:
type: string
details:
type:
- object
- 'null'
credits_used:
type: integer
credits_remaining:
type:
- integer
- 'null'
description: 'THE SUM: purchased balance plus what is left of this month''s free allowance. This is the only number that answers "can I call again" — it is not 0 while you can still call. null means we could not read it, which is not the same as zero.'
credits_purchased_remaining:
type:
- integer
- 'null'
description: Bought credits. These never expire.
free_credits_remaining:
type:
- integer
- 'null'
description: What is left of this month's free allowance.
free_credits_total:
type:
- integer
- 'null'
description: The monthly free allowance for this key.
free_credits_reset_at:
type: string
format: date-time
description: 'When the free allowance resets: 00:00 UTC on the 1st. It is here so the sum dropping at the turn of the month is expected rather than a surprise.'
cached:
type: boolean
description: '`true` is a promise that we did NOT charge: it always comes with `credits_used: 0`.'
request_id:
type: string
Author:
type: object
description: 'The same twelve names on every platform. A field that does not exist there is null, never absent and never zero: zero is a fact about the account, null is a fact about our reading.'
properties:
id:
type:
- string
- 'null'
description: Stable identifier on that platform.
handle:
type:
- string
- 'null'
name:
type:
- string
- 'null'
bio:
type:
- string
- 'null'
avatar_url:
type:
- string
- 'null'
followers:
type:
- integer
- 'null'
following:
type:
- integer
- 'null'
posts_count:
type:
- integer
- 'null'
verified:
type:
- boolean
- 'null'
is_private:
type:
- boolean
- 'null'
external_url:
type:
- string
- 'null'
url:
type:
- string
- 'null'
securitySchemes:
bearerAuth:
type: http
scheme: bearer
description: 'API key, sent as `Authorization: Bearer hk_live_...`. Quota is monthly and renews on the 1st. Unused quota does not roll over and does not expire mid-cycle — you get the whole month.'
x-provenance:
method: harvested
publisher: HonestHook
source: https://honesthook.com/openapi.json
note: split by refine-openapis from the provider's own published document, verified by fetch (openapi/_original/*.fetch.json);
stamped by stamp-openapi-provenance.py (roadmap#793)