diff --git a/README.md b/README.md
index f84aa1c..3addc7c 100644
--- a/README.md
+++ b/README.md
@@ -1,17 +1,73 @@
-RetroAchievements Web API Client
+
+retroachievements-api
+
+
+ A Python library that lets you get achievement, user, and game data from RetroAchievements.
+
+
+
+
+ Documentation: Get Started
+
+
+
+
+
+## Status
+This library is currently a work in progress, endpoint and test coverage can be found below:
+
+ℹ️ Endpoint coverage: 8 of 30
+ℹ️ Test coverage: 0 of 30
+
+## Features
+
+✅ Officially-supported, aligns 1:1 with the RAWeb API.
+✅ Backwards-compatible, easy migration path to API v2.
+✅ Supports Python 3.11+.
+
+
+
+## Documentation
+
+Learn how to authenticate and start pulling data from RetroAchievements on our documentation website.
+
+- [Get started](https://api-docs.retroachievements.org/getting-started.html)
+- [Get a user's profile information](https://api-docs.retroachievements.org/v1/users/get-user-summary.html)
+- [Look up games a user has completed](https://api-docs.retroachievements.org/v1/users/get-user-completed-games.html)
+- [Get a game's metadata](https://api-docs.retroachievements.org/v1/games/get-game-extended.html)
## Installation
-WIP
+Coming Soon
+## How to begin making API calls
-## Usage
+To use any endpoint function in the API, you must first be authorized by RetroAchievements. Fortunately, this is a fairly straightforward process.
-WIP
+1. Visit [your control panel](https://retroachievements.org/controlpanel.php) on the RA website.
-## Testing
+2. Find the "Keys" section on the page. Copy the web API key value. **Do not expose your API key anywhere publicly.**
-WIP
+3. You can now create your authorization object using your web API key.
+
+```python
+from retroachievements import RAClient
+
+userName = ''
+webApiKey = ''
+
+auth = RAClient(userName, webApiKey)
+```
+
+4. You now have all you need to use any function in the API. Each function takes this authorization object as its first argument. Here's an example:
+
+```python
+from retroachievements import getGame
+
+// This returns basic metadata about the game on this page:
+// https://retroachievements.org/game/14402
+game = auth.getGame(14402);
+```
## Contributing
diff --git a/retroachievements/__init__.py b/retroachievements/__init__.py
new file mode 100644
index 0000000..fdff482
--- /dev/null
+++ b/retroachievements/__init__.py
@@ -0,0 +1,14 @@
+"""
+
+RetroAchievements API Client
+---
+
+Official Python API client for RetroAchievements
+
+"""
+
+__title__ = "retroachievements-api"
+__authors__ = "drisc"
+__version__ = "1.0.0"
+
+from .client import RAClient
diff --git a/retroachievements/client.py b/retroachievements/client.py
new file mode 100644
index 0000000..c2e2718
--- /dev/null
+++ b/retroachievements/client.py
@@ -0,0 +1,140 @@
+import requests as request
+from retroachievements import __version__
+
+
+_BASE_URL = "https://retroachievements.org/API/"
+
+
+class RAClient:
+ """
+ Main class for accessing the RetroAhievements Web API
+ """
+
+ headers = {
+ "User-Agent": "RetroAchievements-api-python/" + __version__}
+
+ def __init__(self, username, api_key):
+ self.username = username
+ self.api_key = api_key
+
+ def url_params(self, params=None):
+ """
+ Inserts the auth and query params into the request
+ """
+ if params is None:
+ params = {}
+ params.update({"z": self.username, "y": self.api_key})
+ return params
+
+ # URL construction
+ def _call_api(self, endpoint=None, params=None, timeout=30, headers=None):
+ if endpoint is None:
+ endpoint = {}
+ req = request.get(
+ f"{_BASE_URL}{endpoint}",
+ params=self.url_params(params),
+ timeout=timeout,
+ headers=headers,
+ )
+ return req
+
+ # User endpoints
+
+ def get_user_points(self, user: str) -> dict:
+ """
+ Get a user's total hardcore and softcore points
+
+ Params:
+ u: Username to query
+ """
+ result = self._call_api("API_GetUserPoints.php?", {"u": user}).json()
+ return result
+
+ def get_user_summary(self, user: str,
+ recent_games=0,
+ recent_cheevos=10) -> dict:
+ """
+ Get a user's exhaustive profile metadata
+
+ Params:
+ u: Username to query
+ g: Number of recent games to fetch, default = 0
+ a: Number of recent achievements to fetch, default = 10
+ """
+ result = self._call_api(
+ "API_GetUserSummary.php?",
+ {"u": user, "g": recent_games, "a": recent_cheevos},
+ ).json()
+ return result
+
+ # Game endpoints
+
+ def get_game(self, game: int) -> dict:
+ """
+ Get basic metadata about a game
+
+ Params:
+ i: The game ID to query
+ """
+ result = self._call_api("API_GetGame.php?", {"i": game}).json()
+ return result
+
+ def get_game_extended(self, game: int) -> dict:
+ """
+ Get extended metadata about a game
+
+ Params:
+ i: The game ID to query
+ """
+ result = self._call_api("API_GetGameExtended.php?", {"i": game}).json()
+ return result
+
+ def get_achievement_count(self, game: int) -> dict:
+ """
+ Get the list of achievement ID's for a game
+
+ Params:
+ i: The game ID to query
+ """
+ result = self._call_api(
+ "API_GetAchievementCount.php?", {"i": game}).json()
+ return result
+
+ def get_achievement_distribution(self, game: int) -> dict:
+ """
+ Get how many players have unlocked how many achievements for a game
+
+ Params:
+ i: The game ID to query
+ """
+ result = self._call_api(
+ "API_GetAchievementDistribution.php?", {"i": game}
+ ).json()
+ return result
+
+ # System Endpoints
+
+ def get_console_ids(self) -> list:
+ """
+ Get the complete list of console ID and name pairs on the site
+
+ Params:
+ None
+ """
+ result = self._call_api("API_GetConsoleIDs.php?", {}).json()
+ return result
+
+ def get_game_list(self, system: int, has_cheevos=0, hashes=0) -> dict:
+ """
+ Get the complete list of games for a console
+
+ Params:
+ i: The system ID to query
+ f: If 1, only returns games that have achievements (default = 0)
+ h: If 1, also return the supported hashes for games (default = 0)
+ """
+ result = self._call_api(
+ "API_GetGameList.php?", {
+ "i": system, "f": has_cheevos, "h": hashes}
+ ).json()
+ return result