A Python script can search GIFs.so without a dedicated SDK. The standard library provides URL encoding, HTTP requests, and JSON parsing; your script still needs to check failures and the response shape before using results.
Create a verified account and an API key, then set GIFS_API_KEY in the process environment. Keep it out of source control and command transcripts.
Request one page
import json
import os
from urllib.error import HTTPError, URLError
from urllib.parse import urlencode
from urllib.request import Request, urlopen
params = urlencode({"query": "happy", "limit": 5})
request = Request(
"https://gifs.so/api/rest/gifs?" + params,
headers={"x-api-key": os.environ["GIFS_API_KEY"]},
)
try:
with urlopen(request, timeout=8) as response:
page = json.load(response)
except HTTPError as error:
raise SystemExit(f"GIF API returned HTTP {error.code}")
except (URLError, TimeoutError):
raise SystemExit("GIF API could not be reached")
if not isinstance(page, dict) or not isinstance(page.get("items"), list):
raise SystemExit("Unexpected GIF API response")
for item in page["items"]:
if isinstance(item, dict):
print(item.get("title", "Untitled"), item.get("gifUrl", ""))
This is a terminal search example, not a complete picker UI. A production application should validate each field it consumes against the OpenAPI schema, rather than relying on the minimal structural checks above.
Preserve the rest of the response
Search also returns total, nextOffset, and sponsors. Stop pagination when nextOffset is null; otherwise request that offset with the same inputs. If you build a visual picker, handle the separate sponsor entries with visible sponsorship labels rather than mixing them into GIF data.
The MP4 URL on an item can be null. Use a returned format that exists instead of constructing a filename by changing .gif to .mp4.
Keep automation bounded
Do not put this request in an unlimited loop. GIFs.so’s account allowance is shared across browser, REST, MCP, and keys: 120 authenticated requests per minute and 20,000 per day. Failed calls also consume rate-limit capacity.
Treat 401 as an access problem and 429 as a signal to wait. For scheduled scripts, log the operation and status without the key. The integration guide covers optional request IDs, and the retry article explains how to avoid recording a successful retry as a new logical operation.