gifs.so mascot, a lime animation frame winkinggifs.so
  • The GIF journal
  • Sponsor the stash
U
All guides
September 5, 2026·2 min read·By GIFs.so

Search a GIF API with Python using the standard library

A small Python example with encoded query parameters, an environment-based API key, a timeout, and useful failure states.

APIs

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.

Find the right reaction.

A curated library, a free API, and an MCP server. Sign in with a verified account to get started.

Create an accountIntegration guide

Keep reading

APIsEngineering

Build a React GIF picker with predictable search state

Structure query state, pagination, cancellation, selection, and keyboard behavior before styling a GIF grid.

September 5, 2026·2 min read
APIsSearch

How to compare GIF API providers with a repeatable scorecard

Evaluate real query relevance, media support, limits, access terms, and operational behavior before committing to a provider.

September 5, 2026·2 min read
gifs.so mascot, a lime animation frame winkinggifs.so

5,537 reaction GIFs, sorted into 56 moods. For when you have nothing to say, and need to say it spectacularly.

The stash

  • Join the club
  • Sign in

Around here

  • The GIF journal
  • Sponsor the stash

Say hey

  • hello@gifs.so
© 2026 gifs.soMade for big feelings and very small attention spans.