example-petstore.com

Example domain · Not a live service · Browser visits show this page · API requests get 410 Gone

Guide · Swagger Petstore

Looking for the Swagger Petstore?

The Swagger Petstore is the sample API behind countless Swagger UI and OpenAPI tutorials. It does not live on example-petstore.com. This guide lists its real addresses, shows working requests, and explains how to run your own copy when the public one gets in the way.

The real addresses

Swagger, the API tooling from SmartBear, runs two public versions of the Petstore. Both have the same resources: pets, store orders and users.

VersionBase URL for requestsAPI description and Swagger UI
Petstore 3 (OpenAPI 3.0)https://petstore3.swagger.io/api/v3openapi.json · petstore3.swagger.io
Petstore (Swagger 2.0)https://petstore.swagger.io/v2swagger.json · petstore.swagger.io

New projects are best off with Petstore 3: it follows the OpenAPI 3.0 specification that current tools and code generators expect. The Swagger 2.0 version still answers and appears in older tutorials.

Try it

A few requests with curl. The same paths work in Postman, Insomnia or a generated client once the base URL is set to one of the addresses above.

# Pets with the status "available"
curl -H "Accept: application/json" "https://petstore3.swagger.io/api/v3/pet/findByStatus?status=available"

# Add a pet (name and photoUrls are required)
curl -X POST "https://petstore3.swagger.io/api/v3/pet" \
  -H "Content-Type: application/json" \
  -d '{"id": 12345, "name": "doggie", "photoUrls": [], "status": "available"}'

# Stock per status, with the test key
curl -H "api_key: special-key" "https://petstore.swagger.io/v2/store/inventory"

The same from PHP, with Guzzle:

// PHP, Guzzle: pets with the status "available"
$client = new GuzzleHttp\Client(['base_uri' => 'https://petstore3.swagger.io/api/v3/']);
$response = $client->get('pet/findByStatus', ['query' => ['status' => 'available']]);
$pets = json_decode((string) $response->getBody(), true);

The main paths: /pet, /pet/findByStatus, /pet/findByTags, /pet/{petId}, /store/inventory, /store/order, /user, /user/login and /user/logout.

Keys and sign-in

The Petstore demonstrates two security schemes: an API key in the api_key header and an OAuth 2.0 flow (petstore_auth). The Swagger 2.0 description names special-key as the key for testing the authorization filters. These are demo credentials: never try a real key, token or password against the Petstore.

Shared test data

Everyone uses the same public server. Anything you create can be read, changed or deleted by others, and findByStatus returns whatever other people have added, including odd names and malformed records. A pet you created a moment ago may already be gone.

  • Never send real personal data, customer data or real credentials.
  • Do not build automated tests on the public server: the results are unpredictable, and it is sometimes slow or returns an error (500).
  • For stable results, run your own copy.

Run it locally

The Petstore is open source (Apache 2.0). With Docker it runs in one command:

docker run -d --name petstore -p 8080:8080 swaggerapi/petstore3

# Swagger UI:        http://localhost:8080
# API description:   http://localhost:8080/api/v3/openapi.json
# Base URL:          http://localhost:8080/api/v3

Without Docker, clone swagger-api/swagger-petstore and start it with mvn package jetty:run (also on port 8080). Your own copy starts with the same built-in sample data (ten pets plus a few orders and users) on every run, so tests behave the same each time.

The v1 address that fails

The example file petstore.yaml from the OpenAPI Specification repository lists http://petstore.swagger.io/v1 as its server, with a path /pets. That file illustrates the specification; there is no service behind it. A client generated from it gets 404 Not Found. Point it at https://petstore3.swagger.io/api/v3 or your local copy instead; the paths differ (/pet instead of /pets), so generate the client from openapi.json of Petstore 3.

Ended up here instead?

example-petstore.com is a different name: an example domain from Google’s documentation on Analytics and search. It has no API. Requests to paths such as /v2/pet on this domain get 410 Gone with an explanation in JSON.

  • Check the base URL in your code, .env file, Postman environment or OpenAPI servers field, and replace example-petstore.com with one of the addresses above.
  • Did those requests carry a real key or token? Treat it as exposed: Leaked credentials: what to do now.
  • Keeping base URLs in configuration: Configuring API clients and SDKs.

Sources