Metadata-Version: 2.4
Name: rankright
Version: 1.0.0
Summary: Thin Python client for the RankRight API (SEO tracking + AI Visibility): RPCs, jobs, exports, OAuth, webhook verification.
Author: RankRight
License: MIT
Project-URL: Homepage, https://rankright.dev/
Project-URL: Documentation, https://app.rankright.dev/developers.md
Project-URL: API changelog, https://app.rankright.dev/changelog.md
Keywords: rankright,seo,aeo,ai-visibility,api,mcp
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Internet :: WWW/HTTP
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Requires-Dist: requests>=2.28

# rankright — Python SDK

A thin client for the [RankRight](https://rankright.dev/) API: SEO tracking and AI Visibility (AEO) for agencies. It wraps the documented REST surface — auth, retries, idempotency keys, the error envelope, job polling, exports, OAuth and webhook verification — and contains no business logic of its own. Everything it calls is documented at <https://app.rankright.dev/developers.md>.

```bash
pip install rankright
# or, straight from the app:
pip install https://app.rankright.dev/sdk/rankright-python.zip
```

## Quick start

```python
from rankright import Client, RankRightError

rr = Client(api_key="rrk_...")                       # or Client(access_token="rro_...") after OAuth
                                                      # or set RANKRIGHT_API_KEY in the environment

clients = rr.get_all_clients()                        # every RPC is a method
summary = rr.get_aeo_summary(client_id=12)            # keyword arguments = the RPC's parameters
rr.rpc("update_aeo_item_status", item_id=5, status="done", client_id=12)

try:
    rr.set_aeo_cadence(client_id=12, engines=["claude", "chatgpt-web"])
except RankRightError as e:
    print(e.status, e.code, e.detail, e.hint)         # the API's error envelope, as an exception
```

## Jobs and exports

```python
job = rr.jobs.run("strategist", client_id=12)         # dispatch + wait (raises if the job fails)
job = rr.jobs.create("blog_pipeline", client_id=12)   # dispatch only
rr.jobs.wait(job["job_id"], on_progress=lambda j: print(j["progress_msg"]))

export = rr.exports.run()                             # the whole organization, one zip
rr.exports.download(export, "rankright-export.zip")
```

## OAuth (for CLIs and agents)

```python
from rankright import OAuthFlow, Client

tokens = OAuthFlow("https://app.rankright.dev").login(scopes=["read", "write", "offline_access"])
rr = Client(access_token=tokens["access_token"])
# later: OAuthFlow(...).refresh(tokens["refresh_token"])
```

`login()` registers a public client, opens the consent page in your browser, catches the redirect on a loopback port, and exchanges the code (PKCE). No key to paste.

## Webhooks

```python
from rankright import verify_webhook_signature

ok = verify_webhook_signature(secret, request.headers["X-RankRight-Signature"], request.get_data())
```

## Try it without an account

A public read-only sandbox key is published in <https://app.rankright.dev/llms.txt>; it works for every read RPC and can run the `export_org` job.

## Versioning

The SDK follows semver. The API is path-versioned (`/api/v1`); additive changes ship without notice and are listed in the [changelog](https://app.rankright.dev/changelog.md); breaking changes only arrive in a new version, and removed methods get 60 days' notice with `Deprecation` / `Sunset` headers. Full policy: <https://app.rankright.dev/developers.md#versioning--deprecation>.

MIT licensed.
