The Python SDK
Typed models over /v1 with Retry-After handling built in — generated from the same OpenAPI spec these docs derive from. Python 3.9+, synchronous first.
Install
pip install riilinkOne package on PyPI. Models are typed dataclasses; your editor sees every field the reference documents.
SHELL
pip install riilink
# or: uv add riilink · poetry add riilink
Initialize the client
RiiLink(key)Pass the key from the environment — never inline it. Base URL and retries have working defaults.
PYTHON
import os
from riilink import RiiLink
rii = RiiLink(os.environ["RII_KEY"])
Create and route a link
rii.links.createThe same shape as POST /v1/links — url required, everything else defaulted. Routing rules attach inline or later via rii.links.update.
PYTHON
link = rii.links.create(
url="https://example.com/summer",
slug="summer",
routing=[{"if": {"country": "DE"}, "to": "https://example.de/sommer"}],
)
print(link.short_url) # https://rii.link/summer
YOU SHOULD SEE —the full link object — id, short_url, and the routing list in evaluation order
Handle errors and limits
RiiLinkErrorEvery non-2xx raises RiiLinkError carrying the envelope’s stable code — match on it, never on the message. 429s retry automatically, honoring Retry-After, up to three attempts before the exception surfaces.
PYTHON
from riilink import RiiLinkError
try:
rii.links.create(url=url, slug="summer")
except RiiLinkError as err:
if err.code == "slug_taken":
pass # pick another slug — the envelope names the conflict