Skip to content

HATEOAS Examples — Real-World Hypermedia APIs in Practice

DodaTech Updated 2026-06-28 2 min read

In this tutorial, you will learn about HATEOAS Examples. We cover key concepts, practical examples, and best practices to help you master this topic.

Real-world HATEOAS examples demonstrate hypermedia in production: GitHub's pagination links, Stripe's discoverable actions, and Twilio's resource navigation through hypermedia.

What You'll Learn

  • How major APIs implement hypermedia patterns
  • Practical examples of link relations and pagination
  • Where real APIs follow (and break) HATEOAS principles

Why It Matters

Studying real APIs shows how HATEOAS works in practice and where compromises are made. No major API is 100% HATEOAS-compliant, but many use hypermedia patterns.

Examples

# GitHub API pagination links
import requests

response = requests.get("https://api.github.com/repos/octocat/hello-world/issues")
links = response.links  # Parsed Link header
print("Next page URL:", links.get("next", {}).get("url"))
print("Last page URL:", links.get("last", {}).get("url"))

# GitHub Link header format
# <https://api.github.com/repos/.../issues?page=2>; rel="next"
# <https://api.github.com/repos/.../issues?page=5>; rel="last"
# Stripe API hypermedia patterns
response = requests.post("https://api.stripe.com/v1/payment_intents", 
    auth=("sk_test_...", ""),
    json={"amount": 2000, "currency": "usd"}
)
intent = response.json()
# Stripe returns next_action with instructions
if intent.get("next_action"):
    print("Next action required:", intent["next_action"]["type"])
    # Client follows the next_action to complete payment
# Twilio API resource navigation
response = requests.get(
    "https://api.twilio.com/2010-04-01/Accounts",
    auth=("AC...", "auth_token")
)
accounts = response.json()
for account in accounts.get("accounts", []):
    print("Account SID:", account["sid"])
    # Each account has subresource_uris for messages, calls, etc.
    print("Messages URI:", account.get("subresource_uris", {}).get("messages"))

Common Mistakes

1. Expecting Full HATEOAS Compliance

Most APIs use hypermedia partially. Perfection isn't always practical.

GitHub's Link header is a HATEOAS pattern many clients miss.

3. Not Reading next_action Responses

Stripe explicitly tells clients what to do next. Ignoring it breaks the flow.

4. Hardcoding Subresource URIs

Twilio provides subresource URIs. Use them instead of constructing URLs.

5. Confusing Documentation with HATEOAS

Documentation is not HATEOAS. HATEOAS links are machine-readable, in-band metadata.

Practice Questions

  1. How does GitHub implement HATEOAS for pagination?
  2. What is Stripe's next_action pattern?
  3. How does Twilio expose subresource relationships?
  4. Why do most real APIs use partial HATEOAS?
  5. What is the Link header format for pagination?

Answers:

  1. Through Link headers with rel="next", rel="prev", rel="last".
  2. The API returns next_action with instructions for client-side actions.
  3. Through subresource_uris in each resource response.
  4. Full HATEOAS adds complexity that most APIs don't need.
  5. <url>; rel="relation" — multiple links comma-separated.

Challenge: Trace the hypermedia links in GitHub's API. Start at a user, navigate to their repos, then to issues. Identify all the links you follow.

FAQ

Is GitHub fully HATEOAS-compliant?

: No. GitHub uses hypermedia for pagination but not for full state transitions.

Does Stripe call itself HATEOAS?

: No. Stripe uses hypermedia patterns practically without claiming HATEOAS compliance.

Can I build a generic client for the Twilio API?

: Partially, using subresource_uris for navigation.

What's Next

Build a HATEOAS Mini Project applying all the patterns and examples you've learned.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro