PetstoreAPI Docs
Modern Petstore APIClassic Petstore APIBlog
Modern Petstore APIClassic Petstore APIBlog
  1. Modern Petstore API
  • Modern Pet Store API: A New Gold Standard for OpenAPI
  • Pet
    • Get Pet
      GET
    • Update Pet
      PUT
    • Delete Pet
      DELETE
    • Create Pet
      POST
    • List Pets
      GET
    • Upload Pet Image
      POST
  • Chat
    • Create Chat Completion
      POST
  • Payments
    • Pay Order
      POST
  • Store
    • List Inventory
      GET
    • Create Order
      POST
    • Get Order
      GET
    • Delete Order
      DELETE
    • Callback Example
      POST
  • User
    • Create User
      POST
    • Update User
      PUT
    • Get User
      GET
    • Delete User
      DELETE
    • Login
      POST
    • Logout
      POST
  • Webhooks
    • Pet Adopted Event
    • New Pet Available Event
  • Schemas
    • Pet
    • PetCollection
    • User
    • OrderPayment
    • Bank Card
    • Bank Account
    • Category
    • Links
    • Order
    • ApiResponse
    • Tag
    • Error
Modern Petstore APIClassic Petstore APIBlog
Modern Petstore APIClassic Petstore APIBlog
  1. Modern Petstore API

Modern Pet Store API: A New Gold Standard for OpenAPI

Building the API Example the Industry Deserves


The Problem with the Old Petstore

For over a decade, every developer learning OpenAPI (formerly Swagger) has encountered the same example: the Petstore API. While it served its purpose as a teaching tool, the original Petstore has become outdated, failing to reflect modern API design practices and the full capabilities of OpenAPI 3.x specifications.

🚨 Critical Issue: Violation of RESTful Principles

The biggest problem? The old Petstore doesn't even follow basic RESTful design principles. This is catastrophic because it teaches developers anti-patterns that they carry into production systems.

Here are the specific RESTful violations in the original Swagger Petstore:

1. Plural vs Singular Resource Names

❌ BAD (Old Petstore):
/pet/{id}         ← Singular (incorrect)
/store/inventory  ← Plural (inconsistent)

βœ… GOOD (Modern Petstore):
/pets/{id}        ← Always plural for collections
/orders/{id}      ← Consistent pattern

Problem: Inconsistent naming confuses developers and breaks conventions.

2. Non-RESTful URL Design

❌ BAD (Old Petstore):
GET /pet/findByStatus?status=available  ← Action verb in URL
GET /pet/findByTags?tags=tag1,tag2      ← Action verb in URL

βœ… GOOD (Modern Petstore):
GET /pets?status=AVAILABLE              ← Resource-oriented
QUERY /pets/search                       ← Complex queries use QUERY method

Problem: URLs should represent resources (nouns), not actions (verbs).

3. Missing Standard HTTP Status Codes

❌ BAD (Old Petstore):
POST /pet β†’ Returns 200 OK (should be 201 Created)
DELETE /pet/{id} β†’ Returns 200 with body (should be 204 No Content)

βœ… GOOD (Modern Petstore):
POST /pets β†’ Returns 201 Created + Location header
DELETE /pets/{id} β†’ Returns 204 No Content

Problem: Incorrect status codes confuse clients and break HTTP semantics.

3. Wrong HTTP Methods for Authentication

❌ BAD (Old Petstore):
GET /user/login?username=john&password=secret123

βœ… GOOD (Modern Petstore):
POST /login
Content-Type: application/json
{
  "username": "john",
  "password": "secret123"
}

Problem: The old Petstore uses GET for login, which:

  • Exposes passwords in URL query parameters (visible in browser history, server logs, referrer headers)
  • Violates the HTTP specification (GET must be safe and idempotent)
  • Creates a massive security vulnerability
  • Is NOT cacheable despite using GET

5. No Collection Wrappers

❌ BAD (Old Petstore):
GET /pets β†’ Returns bare array
[
  {"id": 1, "name": "Fluffy"},
  {"id": 2, "name": "Buddy"}
]

βœ… GOOD (Modern Petstore):
GET /pets β†’ Returns wrapped collection with metadata
{
  "data": [...],
  "pagination": {
    "page": 1,
    "limit": 20,
    "totalItems": 45,
    "totalPages": 3
  },
  "links": {
    "self": "...",
    "next": "..."
  }
}

Problem: Bare arrays can't be extended with metadata, breaking forward compatibility.

Other Critical Problems

Beyond RESTful violations, the old Petstore has:

  • Poor error handling: Generic error messages without structured validation
  • Weak security models: API keys in query parameters (another security disaster)
  • Missing standards: No RFC 9457 error format, outdated X-RateLimit headers
  • Incomplete examples: Lacks webhooks, SSE, polymorphic types, HATEOAS
  • Non-production ready: No rate limiting, no proper validation, no real business logic

Teaching developers with the old Petstore is like teaching driving with a car that has the brake and gas pedals swapped. It actively harms the industry.

It was time for a complete rewrite.


Introducing Modern Pet Store API

We've built a completely reimagined Petstore API from the ground upβ€”one that showcases current best practices and demonstrates the full power of OpenAPI 3.2. This isn't just an update; it's a comprehensive reference implementation designed to be the new industry standard.

Our Mission

Create a pet store API that:

  • βœ… Demonstrates every OpenAPI 3.2 feature with production-ready examples
  • βœ… Follows current web standards (RFC 9457, IETF rate limiting, ISO formats)
  • βœ… Provides realistic business logic (payments, webhooks, AI features)
  • βœ… Includes comprehensive code samples across multiple languages
  • βœ… Serves as a learning resource for API designers and developers
  • βœ… Can be deployed to production with minimal modifications

What Makes It Modern?

βœ… First and Foremost: True RESTful Design

This is the foundation everything else builds on. We follow RESTful principles rigorously:

1. Correct HTTP Methods for Every Operation

# Authentication
POST /login          ← POST for state-changing operations
POST /logout         ← POST (not GET)

# Resource Operations
GET    /pets         ← Safe, idempotent retrieval
POST   /pets         ← Create new resource
GET    /pets/{id}    ← Retrieve specific resource
PUT    /pets/{id}    ← Full update (idempotent)
PATCH  /pets/{id}    ← Partial update (idempotent)
DELETE /pets/{id}    ← Remove resource (idempotent)

Every method follows HTTP semantics:

  • GET: Safe (no side effects) and idempotent
  • POST: Create resources, submit forms, non-idempotent operations
  • PUT/PATCH: Idempotent updates
  • DELETE: Idempotent removal

2. Proper HTTP Status Codes

We use the right status code for every situation:

# Success Codes
201 Created          ← POST success + Location header pointing to new resource
200 OK               ← GET/PUT/PATCH success
204 No Content       ← DELETE success (no response body)

# Client Error Codes
400 Bad Request      ← Malformed request (invalid JSON, wrong content-type)
401 Unauthorized     ← Missing or invalid authentication
403 Forbidden        ← Authenticated but lacks permission
404 Not Found        ← Resource doesn't exist
409 Conflict         ← Resource conflict (duplicate creation)
422 Unprocessable    ← Valid request but validation failed

# Server Error Codes
500 Internal Error   ← Server-side failure
503 Service Unavailable ← Temporary service disruption

Example response with proper status code:

HTTP/1.1 201 Created
Location: https://api.petstoreapi.com/v1/pets/pet_d0g_8n2q4w
Content-Type: application/json

{
  "id": "pet_d0g_8n2q4w",
  "species": "DOG",
  "name": "Buddy",
  ...
}

3. Resource-Oriented URL Design

URLs represent resources (nouns), not actions (verbs):

❌ BAD:
/getPets
/createPet
/updatePet
/deletePet
/findPetsByStatus

βœ… GOOD:
GET    /pets
POST   /pets
PUT    /pets/{id}
DELETE /pets/{id}
GET    /pets?status=AVAILABLE

For complex operations that don't fit CRUD, we use:

  • Sub-resources: POST /orders/{id}/payment
  • Query parameters: GET /pets?status=AVAILABLE&species=DOG
  • QUERY method (OpenAPI 3.2): QUERY /pets/search with request body

4. Consistent Plural Nouns for Collections

βœ… Always use plural:
/pets           ← Collection
/pets/{id}      ← Single resource from collection
/users          ← Collection
/users/{id}     ← Single resource
/orders         ← Collection
/orders/{id}    ← Single resource

This consistency makes APIs predictable and intuitive.

5. Uniform Path Parameter Naming

βœ… Root resources use {id}:
/pets/{id}
/users/{id}
/orders/{id}

βœ… Nested resources use {parentId} for parent, {id} for child:
/users/{userId}/pets/{id}
/orders/{orderId}/items/{id}

Why this matters: Clients can predict URL patterns without reading docs.

6. Collection Wrappers with Pagination

Every collection endpoint returns a consistent structure:

{
  "data": [
    { "id": "pet_c4t_5x7k9m", "name": "Whiskers", ... },
    { "id": "pet_d0g_8n2q4w", "name": "Buddy", ... }
  ],
  "pagination": {
    "page": 1,
    "limit": 20,
    "totalItems": 145,
    "totalPages": 8
  },
  "links": {
    "self": "https://api.petstoreapi.com/v1/pets?page=1",
    "next": "https://api.petstoreapi.com/v1/pets?page=2",
    "prev": null,
    "first": "https://api.petstoreapi.com/v1/pets?page=1",
    "last": "https://api.petstoreapi.com/v1/pets?page=8"
  }
}

Benefits:

  • Never break pagination: Add totalItems later without breaking clients
  • HATEOAS navigation: Clients follow links, not construct URLs
  • Consistent structure: Every collection works the same way

7. HATEOAS (Hypermedia as the Engine of Application State)

Every resource includes navigational links:

{
  "id": "pet_c4t_5x7k9m",
  "name": "Whiskers",
  "species": "CAT",
  "status": "AVAILABLE",
  "links": {
    "self": "https://api.petstoreapi.com/v1/pets/pet_c4t_5x7k9m",
    "adopt": "https://api.petstoreapi.com/v1/adoptions",
    "images": "https://api.petstoreapi.com/v1/pets/pet_c4t_5x7k9m/images"
  }
}

Clients can:

  • Discover available operations
  • Navigate without hardcoding URLs
  • Evolve independently from URL changes

8. Content Negotiation

Support multiple representations:

GET /pets/{id}
Accept: application/json      ← Returns JSON
Accept: application/xml       ← Returns XML (if supported)

We standardize on JSON but the pattern supports future formats.

9. Idempotency Where Required

Operations that should be idempotent are:

βœ… Idempotent (same result when called multiple times):
GET    /pets/{id}      ← Always returns same pet
PUT    /pets/{id}      ← Update to same state produces same result
DELETE /pets/{id}      ← Deleting twice same as deleting once
PATCH  /pets/{id}      ← Partial update to same fields is idempotent

❌ Not idempotent (different result each time):
POST   /pets           ← Creates new pet with new ID each time
POST   /orders         ← Creates new order each time

This allows safe retries on network failures.

10. Caching Support

We include proper cache headers:

HTTP/1.1 200 OK
Cache-Control: public, max-age=300
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
Last-Modified: Tue, 15 Nov 2025 12:45:26 GMT

# Conditional requests
GET /pets/{id}
If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"

HTTP/1.1 304 Not Modified

This reduces bandwidth and improves performance.


πŸ†• OpenAPI 3.2 Exclusive Features

Beyond RESTful fundamentals, we leverage the latest OpenAPI 3.2 specification features:

Hierarchical Tags

Organize your API endpoints with structured tagging:

tags:
  - name: Store
    summary: Store operations
    kind: category
  - name: Pet
    summary: Pet management
    parent: Store  # Nested under Store
    kind: resource

This creates a clean hierarchy in documentation tools, making large APIs easier to navigate.

QUERY HTTP Method

For complex searches that exceed URL length limits:

// Traditional GET has URL length limits
GET /pets?species=dog&age_min=12&age_max=36&good_with_kids=true...

// QUERY method uses request body while maintaining safe, idempotent semantics
QUERY /pets/search
{
  "criteria": {
    "species": ["DOG", "CAT"],
    "ageRange": { "min": 12, "max": 36 },
    "compatibility": { "goodWithKids": true }
  },
  "sort": { "field": "ageMonths", "order": "ASC" }
}

OAuth Device Flow

Perfect for smart TVs, IoT devices, and kiosks:

securitySchemes:
  oauth2:
    flows:
      deviceCode:
        deviceAuthorizationUrl: https://auth.petstoreapi.com/device/authorize
        tokenUrl: https://auth.petstoreapi.com/token
        scopes:
          read:pets: View pet information
          write:pets: Manage pets

Reusable Path Items

DRY principle for consistent resource patterns:

components:
  pathItems:
    PetResource:
      get:
        summary: Get Pet
      put:
        summary: Update Pet
      delete:
        summary: Delete Pet

paths:
  /pets/{id}:
    $ref: '#/components/pathItems/PetResource'

πŸ“š Modern API Standards

We don't just follow OpenAPIβ€”we implement current web standards across the board:

RFC 9457: Problem Details for HTTP APIs

No more generic error messages. Every error response follows the standard:

{
  "type": "https://petstoreapi.com/errors/validation-error",
  "title": "Validation Error",
  "status": 422,
  "detail": "The request body contains validation errors",
  "instance": "/v1/pets",
  "errors": [
    {
      "field": "ageMonths",
      "message": "Must be a positive number",
      "code": "INVALID_FORMAT"
    }
  ]
}

Notice how it provides:

  • Structured field-level errors - developers know exactly what to fix
  • Unique error type URLs - link to detailed documentation
  • Machine-readable error codes - enable programmatic handling

IETF Rate Limiting Headers

We use the modern standard, not legacy X-RateLimit headers:

RateLimit-Limit: 100
RateLimit-Remaining: 95
RateLimit-Reset: 1640000000

ISO Standard Data Formats

  • ISO 3166-1 alpha-2: Country codes (US, GB, CA)
  • ISO 4217: Currency codes (USD, EUR, GBP)
  • ISO 8601 / RFC 3339: Timestamps (2025-12-17T08:00:00Z)

This ensures international compatibility and eliminates ambiguity.


🎨 Real-World API Patterns

Modern APIs aren't simple CRUD operations. We demonstrate complex, production-ready patterns:

Polymorphic Payment Sources

Support multiple payment methods with discriminators:

{
  "amount": 150.00,
  "currency": "USD",
  "source": {
    "object": "CARD",
    "name": "Jane Doe",
    "number": "4242424242424242",
    "expMonth": 12,
    "expYear": 2025,
    "cvc": "123"
  }
}

// Or pay with bank account
{
  "amount": 150.00,
  "currency": "USD",
  "source": {
    "object": "BANK_ACCOUNT",
    "accountHolderName": "Jane Doe",
    "routingNumber": "110000000",
    "accountNumber": "000123456789",
    "accountType": "CHECKING"
  }
}

The OpenAPI spec uses discriminators to validate the correct fields based on object type:

discriminator:
  propertyName: object
  mapping:
    CARD: '#/components/schemas/CardPaymentSource'
    BANK_ACCOUNT: '#/components/schemas/BankAccountPaymentSource'

Collection Wrappers & HATEOAS

Never return bare arrays. Every collection response includes:

{
  "data": [
    {
      "id": "pet_c4t_5x7k9m",
      "species": "CAT",
      "name": "Whiskers",
      "links": {
        "self": "https://api.petstoreapi.com/v1/pets/pet_c4t_5x7k9m",
        "adopt": "https://api.petstoreapi.com/v1/adoptions"
      }
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 20,
    "totalItems": 45,
    "totalPages": 3
  },
  "links": {
    "self": "https://api.petstoreapi.com/v1/pets?page=1",
    "next": "https://api.petstoreapi.com/v1/pets?page=2",
    "last": "https://api.petstoreapi.com/v1/pets?page=3"
  }
}

Benefits:

  • Pagination metadata - clients know exactly where they are
  • HATEOAS links - API is self-documenting and discoverable
  • Consistent structure - all collections follow the same pattern

Webhooks for Event-Driven Architecture

OpenAPI 3.x supports webhook definitions. We demonstrate real-world events:

webhooks:
  petAdopted:
    post:
      summary: Pet Adopted Event
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                eventId:
                  type: string
                  format: uuid
                eventType:
                  type: string
                  const: pet.adopted
                timestamp:
                  type: string
                  format: date-time
                data:
                  type: object
                  properties:
                    pet:
                      $ref: '#/components/schemas/Pet'
                    adopter:
                      $ref: '#/components/schemas/User'

Your application receives events when important actions occurβ€”no polling needed.

Server-Sent Events (SSE) for Real-Time Streaming

AI features need streaming responses. We demonstrate with a Pet Adoption Advisor:

const response = await fetch('https://api.petstoreapi.com/v1/chat/completions', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer YOUR_TOKEN'
  },
  body: JSON.stringify({
    messages: [
      { role: 'USER', content: 'What should I know before adopting a cat?' }
    ],
    model: 'PET_ADVISOR_1',
    stream: true
  })
});

// Stream tokens as they arrive
const reader = response.body.getReader();
const decoder = new TextDecoder();

while (true) {
  const { done, value } = await reader.read();
  if (done) break;

  const chunk = decoder.decode(value);
  const lines = chunk.split('\n').filter(line => line.trim());

  for (const line of lines) {
    if (line.startsWith('data: ')) {
      const data = JSON.parse(line.slice(6));
      process.stdout.write(data.choices[0]?.delta?.content || '');
    }
  }
}

The OpenAPI spec documents the SSE format with text/event-stream media type.


πŸ’» Developer Experience

Great APIs are easy to use. We've focused heavily on developer experience:

Multi-Language Code Examples

Every major operation includes x-codeSamples with ready-to-use examples:

TypeScript:

import { PetStoreAPI } from '@petstoreapi/sdk';

const client = new PetStoreAPI({
  apiKey: process.env.PETSTORE_API_KEY
});

const pet = await client.pets.get('pet_c4t_5x7k9m');
console.log(`Found ${pet.name}, a ${pet.ageMonths}-month-old ${pet.species}`);

Python:

from petstore import PetStoreAPI

client = PetStoreAPI(api_key=os.environ['PETSTORE_API_KEY'])
pet = client.pets.get('pet_c4t_5x7k9m')
print(f"Found {pet.name}, a {pet.age_months}-month-old {pet.species}")

cURL:

curl https://api.petstoreapi.com/v1/pets/pet_c4t_5x7k9m \
  -H "Accept: application/json"

Workflow Descriptions

Every operation includes business context, not just technical details:

description: |
  Add a new pet to the store catalog, making it available for adoption.

  ## Pet Lifecycle Workflow

  When a new pet enters the system:

  1. **Intake**: Staff creates a pet record with this endpoint (status: `AVAILABLE`)
  2. **Profile**: Pet details include species, breed, age, medical info, photos
  3. **Discovery**: Pet appears in search results and listings
  4. **Adoption Application**: Potential adopters can apply
  5. **Adoption**: Once approved, pet status changes to `ADOPTED`

  **Access**: Requires staff permissions (`write:pets` scope or Bearer token).

External Documentation Links

Complex features link to detailed guides:

externalDocs:
  description: Learn more about webhooks
  url: https://petstoreapi.com/docs/webhooks

Technical Architecture

Built for the Edge

We've chosen a modern, performant stack:

  • Cloudflare Workers: Edge computing with <50ms global latency
  • Hono: Fast, lightweight web framework built for edge runtimes
  • TypeScript: End-to-end type safety
  • Cloudflare KV: Persistent, globally distributed storage

This isn't a toy exampleβ€”it's production infrastructure.

Type Safety Everywhere

// Types generated from OpenAPI schema
interface Pet {
  id: string;
  species: 'DOG' | 'CAT' | 'RABBIT' | 'BIRD' | 'REPTILE' | 'OTHER';
  name: string;
  ageMonths: number;
  status: 'AVAILABLE' | 'PENDING' | 'ADOPTED' | 'NOT_AVAILABLE';
  // ... more fields
}

// Request handlers are fully typed
export async function getPet(c: Context): Promise<Pet> {
  const petId = c.req.param('id');
  const pet = await petStore.get(petId);

  if (!pet) {
    throw errors.notFound('Pet not found');
  }

  return pet;
}

Comprehensive Validation

We use unevaluatedProperties: false to catch unexpected fields:

Pet:
  type: object
  required: [id, name, species, ageMonths, status]
  properties:
    id: { type: string }
    name: { type: string }
    # ...
  unevaluatedProperties: false  # Reject unknown fields

This prevents clients from sending invalid data and makes API evolution explicit.


Comparison: Old vs. New

Let's see how we stack up against the original Swagger Petstore and other modern examples. RESTful compliance is listed first as it's the foundation:

FeatureOld PetstoreTrain Travel APIModern Petstore
πŸ”΄ RESTful: HTTP Methods❌ GET for login/logoutβœ… POST for mutationsβœ… Correct methods everywhere
πŸ”΄ RESTful: Status Codes❌ 200 for POST/DELETEβœ… Proper codesβœ… 201/204/4xx/5xx properly
πŸ”΄ RESTful: URL Design❌ /findByStatus (verbs)βœ… Resource-orientedβœ… Pure resource nouns
πŸ”΄ RESTful: Plural Resources❌ /pet (singular)βœ… /trips (plural)βœ… /pets, /users, /orders
πŸ”΄ RESTful: Path Parameters❌ /user/{username} mixedβœ… Consistentβœ… {id} uniformly
πŸ”΄ RESTful: Collections❌ Bare arraysβœ… Wrappedβœ… Wrapped + pagination + links
πŸ”΄ RESTful: HATEOAS❌ None⚠️ Basic linksβœ… Full hypermedia
πŸ”΄ RESTful: Idempotency❌ Not documentedβœ… Documentedβœ… Explicit + safe retries
OpenAPI Version2.03.1.03.2.0 βœ…
Error StandardCustomRFC 9457RFC 9457 + Field Details βœ…
Rate LimitingX-RateLimitRateLimit-*RateLimit-* βœ…
Auth MethodsAPI Key in URLOAuthOAuth + Bearer/JWT βœ…
OAuth FlowsNoneAuthorization CodeAuth Code + Device Flow βœ…
WebhooksNoneBasicComplete with Security βœ…
Real-time (SSE)NoneNoneFull SSE Implementation βœ…
QUERY MethodNoneNoneYes (OpenAPI 3.2) βœ…
Hierarchical TagsNoneFlatFull Hierarchy βœ…
Code SamplesNoneBasicMulti-language x-codeSamples βœ…
Polymorphic TypesNoneBasicDiscriminators with Mapping βœ…
Production ReadyNoPartialFully Deployable βœ…

Result: We lead in every category, with RESTful compliance being our strongest differentiator.

The Bottom Line

The old Petstore violates 8 out of 8 core RESTful principles. This isn't just outdatedβ€”it's teaching harmful patterns. Every developer who learned from it has to unlearn those anti-patterns.

The Modern Petstore follows 100% of RESTful principles plus modern extensions like QUERY method and HATEOAS.


Real-World Use Cases

This isn't just an exampleβ€”it's a template for building production APIs:

🐾 Pet Adoption Platform

The obvious use case. Organizations can fork this and customize:

  • Add shelter locations with geospatial search
  • Integrate with local regulations and licensing
  • Add foster care management
  • Implement application review workflows

πŸ₯ Healthcare Appointment Systems

The patterns translate perfectly:

  • Pets β†’ Patients
  • Adoption Status β†’ Appointment Status
  • Medical Info β†’ Patient Records
  • Webhooks for appointment reminders

πŸ›’ E-Commerce Platforms

Same structural patterns:

  • Pets β†’ Products
  • Adoption β†’ Purchase
  • Species/Breed β†’ Categories
  • Polymorphic payments already implemented

πŸ“š Resource Booking Systems

Libraries, equipment rentals, room bookings:

  • Pets β†’ Resources
  • Availability Status β†’ Booking Status
  • User accounts and authentication ready
  • Search and filtering patterns established

Getting Started

Quick Start

# Clone the repository
git clone https://github.com/your-org/petstoreapi.com.git
cd petstoreapi.com/packages/api

# Install dependencies
npm install

# Start local development
npm run dev

# API available at http://localhost:8787

Explore the API

# Seed sample data
curl -X POST http://localhost:8787/v1/seed

# List pets
curl http://localhost:8787/v1/pets

# Get specific pet
curl http://localhost:8787/v1/pets/pet_cat_5x7k9m

# Try AI chat
curl -X POST http://localhost:8787/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "messages": [{"role": "USER", "content": "Tell me about Golden Retrievers"}],
    "stream": false
  }'

View Documentation

  • Swagger UI: http://localhost:8787/v1/docs
  • AsyncAPI UI: http://localhost:8787/v1/async-docs
  • OpenAPI Spec: http://localhost:8787/v1/openapi.json
  • AsyncAPI Spec: http://localhost:8787/v1/asyncapi.json

Learning Resources

For API Designers

Study our OpenAPI spec to learn:

  • How to structure complex schemas with discriminators
  • When to use readOnly vs writeOnly
  • How to document workflows with descriptions
  • How to organize tags hierarchically
  • When to use references vs inline schemas

For API Developers

Learn implementation patterns:

  • Structured error handling with RFC 9457
  • Rate limiting middleware
  • OAuth 2.0 implementation
  • Webhook delivery with retries
  • SSE streaming for real-time data

For Technical Writers

See how to document:

  • Complex authentication flows
  • Multi-step business workflows
  • Error scenarios with examples
  • Code samples in multiple languages
  • External resource links

Design Principles

These principles guided every decision:

1. Standards Over Custom

We prefer established standards (RFC 9457, ISO codes, IETF headers) over inventing our own. Standards are:

  • Already documented
  • Widely understood
  • Supported by tools
  • Battle-tested

2. Production-Ready Over Simplified

Examples that are "too simple" teach bad habits. We include:

  • Proper error handling
  • Rate limiting
  • Security models
  • Validation
  • Pagination

3. Realistic Over Theoretical

We model actual business logic:

  • Payment processing with multiple methods
  • Multi-step workflows (adoption application β†’ approval β†’ completion)
  • Webhook event delivery
  • AI integration

4. Modern Over Compatible

We target the latest specifications:

  • OpenAPI 3.2 (not 3.0 or 2.0)
  • JSON Schema 2020-12
  • Current RFC standards

If you need older versions, this shows what you're missing.

5. Complete Over Minimal

Every feature is fully implemented:

  • All CRUD operations
  • Search and filtering
  • Pagination
  • Webhooks
  • Streaming responses

No "TODO" comments or stub implementations.


What's Next?

We're continuously improving the Modern Petstore API:

Coming Soon

  • AsyncAPI 3.0 Specification: Complete async/event documentation
  • Arazzo Workflows: Step-by-step workflow definitions
  • GraphQL Endpoint: Demonstrate REST + GraphQL coexistence
  • More Code Samples: Go, Java, PHP, Ruby
  • Performance Benchmarks: Quantified edge performance metrics
  • Video Tutorials: Walkthrough of key features

Community

This project thrives on community contributions:

  • GitHub Discussions: Share use cases and ask questions
  • Issues: Report bugs or request features
  • Pull Requests: Contribute improvements
  • Blog Posts: Write about how you're using the API
  • Translations: Help document in other languages

Conclusion

The Modern Pet Store API isn't just an updateβ€”it's a reimagining of what an API example should be:

βœ… Complete OpenAPI 3.2 showcase
βœ… Current web standards throughout
βœ… Production-ready architecture
βœ… Real-world business patterns
βœ… Comprehensive documentation
βœ… Multi-language code samples
βœ… Deployable to Cloudflare Edge

Whether you're learning OpenAPI, designing a new API, evaluating API tools, or teaching others, the Modern Pet Store API provides a comprehensive, realistic reference.

The classic Petstore served us well for over a decade. Now it's time for a new standard.


Try It Now

Live API: https://api.petstoreapi.com
Interactive Docs: https://api.petstoreapi.com/v1/docs
GitHub: https://github.com/your-org/petstoreapi.com
OpenAPI Spec: https://api.petstoreapi.com/v1/openapi.json

Give it a star ⭐ if you find it useful!


About the Project

The Modern Pet Store API is an open-source project created to demonstrate best practices in API design. It's maintained by the community and welcomes contributions from developers worldwide.

Built with ❀️ using:

  • OpenAPI 3.2
  • TypeScript
  • Hono
  • Cloudflare Workers
  • Modern Web Standards

License: MIT


Last updated: December 2025

Modified atΒ 2025-12-17 11:58:08
Next
Get Pet
Built with