Skip to main content

API Documentation

Official Specifications

  • OpenAPI 3.2 Spec (REST, SSE): JSON | YAML
  • AsyncAPI 3.0 Spec (WebSocket, Socket.IO, MQTT): JSON | YAML

Interactive Documentation


API Endpoints by Protocol

REST API (HTTPS)

Base URL: https://api.petstoreapi.com/v1

Server-Sent Events (SSE)

Endpoint: https://api.petstoreapi.com/v1/chat/completions (with stream: true)

WebSocket

Endpoint: wss://api.petstoreapi.com/v1/ws/chat

Socket.IO

Endpoint: wss://api.petstoreapi.com

MQTT (IoT)

Endpoint: mqtts://mqtt.petstoreapi.com:8883

Quick Examples

1. REST API

List Available Pets

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

Get a Specific Pet

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

Create a New Pet (Authenticated)

curl -X POST https://api.petstoreapi.com/v1/pets \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -d '{
    "name": "Buddy",
    "species": "DOG",
    "breed": "Golden Retriever",
    "ageMonths": 24,
    "status": "AVAILABLE",
    "adoptionFee": 150.00,
    "currency": "USD"
  }'

Search Pets with Filters

curl "https://api.petstoreapi.com/v1/pets?species=DOG&status=AVAILABLE&page=1&limit=20" \
  -H "Accept: application/json"

Advanced Search with QUERY Method

curl -X QUERY https://api.petstoreapi.com/v1/pets/search \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "criteria": {
      "species": ["DOG", "CAT"],
      "ageRange": {
        "min": 12,
        "max": 36
      },
      "compatibility": {
        "goodWithKids": true,
        "goodWithDogs": true
      }
    },
    "sort": {
      "field": "ageMonths",
      "order": "ASC"
    },
    "pagination": {
      "page": 1,
      "limit": 20
    }
  }'

Create an Order

curl -X POST https://api.petstoreapi.com/v1/orders \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -d '{
    "items": [
      {
        "productId": "prod_abc123",
        "quantity": 2,
        "price": 29.99
      }
    ],
    "shippingAddress": {
      "street": "123 Main St",
      "city": "San Francisco",
      "state": "CA",
      "postalCode": "94102",
      "country": "US"
    }
  }'

2. Server-Sent Events (SSE)

AI Chat with Streaming Response

JavaScript Example:
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 Golden Retriever?'
      }
    ],
    model: 'PET_ADVISOR_1',
    stream: true
  })
});

// Process SSE stream
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));

      // Handle completion
      if (data.choices?.[0]?.delta?.content) {
        process.stdout.write(data.choices[0].delta.content);
      }

      // Handle stream end
      if (data.choices?.[0]?.finishReason === 'STOP') {
        console.log('\n--- Stream completed ---');
      }
    }
  }
}
cURL Example:
curl -N -X POST https://api.petstoreapi.com/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -d '{
    "messages": [
      {
        "role": "USER",
        "content": "Tell me about adopting cats"
      }
    ],
    "model": "PET_ADVISOR_1",
    "stream": true
  }'

3. WebSocket

Customer Support Chat

JavaScript Example:
// Connect to WebSocket with authentication
const ws = new WebSocket('wss://api.petstoreapi.com/v1/ws/chat?token=YOUR_JWT_TOKEN');

// Connection opened
ws.addEventListener('open', (event) => {
  console.log('Connected to chat');

  // Send a message
  ws.send(JSON.stringify({
    type: 'chatMessage',
    payload: {
      conversationId: 'conv_abc123',
      senderId: 'user_xyz789',
      content: 'Hello, I need help with my order',
      timestamp: new Date().toISOString()
    }
  }));
});

// Listen for messages
ws.addEventListener('message', (event) => {
  const message = JSON.parse(event.data);

  switch (message.type) {
    case 'chatMessage':
      console.log('Message received:', message.payload.content);
      break;

    case 'messageDelivered':
      console.log('Message delivered:', message.payload.messageId);
      break;

    case 'messageRead':
      console.log('Message read:', message.payload.messageId);
      break;

    case 'typingStarted':
      console.log('User is typing...');
      break;

    case 'typingStopped':
      console.log('User stopped typing');
      break;
  }
});

// Send typing indicator
function startTyping() {
  ws.send(JSON.stringify({
    type: 'typingStarted',
    payload: {
      conversationId: 'conv_abc123',
      userId: 'user_xyz789'
    }
  }));
}

// Connection closed
ws.addEventListener('close', (event) => {
  console.log('Disconnected from chat');
});

// Handle errors
ws.addEventListener('error', (event) => {
  console.error('WebSocket error:', event);
});
Python Example:
import asyncio
import websockets
import json

async def chat_client():
    uri = "wss://api.petstoreapi.com/v1/ws/chat?token=YOUR_JWT_TOKEN"

    async with websockets.connect(uri) as websocket:
        # Send a message
        await websocket.send(json.dumps({
            "type": "chatMessage",
            "payload": {
                "conversationId": "conv_abc123",
                "senderId": "user_xyz789",
                "content": "Hello, I need help with my order",
                "timestamp": "2025-01-04T10:00:00Z"
            }
        }))

        # Receive messages
        async for message in websocket:
            data = json.loads(message)
            print(f"Received: {data['type']}")

            if data['type'] == 'chatMessage':
                print(f"Message: {data['payload']['content']}")

asyncio.run(chat_client())

4. Socket.IO

Real-time Support Chat

JavaScript Example:
import { io } from 'socket.io-client';

// Connect to Socket.IO server
const socket = io('wss://api.petstoreapi.com', {
  auth: {
    token: 'YOUR_JWT_TOKEN'
  },
  transports: ['websocket']
});

// Connection events
socket.on('connect', () => {
  console.log('Connected to Socket.IO server');
  console.log('Socket ID:', socket.id);
});

socket.on('disconnect', () => {
  console.log('Disconnected from server');
});

// Join support chat
socket.emit('joinChat', {
  conversationId: 'conv_abc123',
  userId: 'user_xyz789'
});

// Send chat message
socket.emit('chatMessage', {
  conversationId: 'conv_abc123',
  content: 'I need help with my order',
  timestamp: new Date().toISOString()
});

// Listen for incoming messages
socket.on('chatMessage', (data) => {
  console.log('New message:', data.content);
  console.log('From:', data.senderId);
  console.log('Time:', data.timestamp);
});

// Agent assignment notification
socket.on('agentAssigned', (data) => {
  console.log('Agent assigned:', data.agentId);
  console.log('Agent name:', data.agentName);
});

// Typing indicators
socket.on('typingStarted', (data) => {
  console.log(`${data.userId} is typing...`);
});

socket.on('typingStopped', (data) => {
  console.log(`${data.userId} stopped typing`);
});

// Send typing indicator
function startTyping() {
  socket.emit('typingStarted', {
    conversationId: 'conv_abc123'
  });
}

function stopTyping() {
  socket.emit('typingStopped', {
    conversationId: 'conv_abc123'
  });
}
Node.js Example:
const { io } = require('socket.io-client');

const socket = io('wss://api.petstoreapi.com', {
  auth: {
    token: process.env.PETSTORE_API_TOKEN
  },
  transports: ['websocket']
});

socket.on('connect', () => {
  console.log('Connected!');

  // Join chat room
  socket.emit('joinChat', {
    conversationId: 'conv_abc123',
    userId: 'user_xyz789'
  });
});

socket.on('chatMessage', (message) => {
  console.log(`[${message.timestamp}] ${message.senderId}: ${message.content}`);
});

socket.on('agentAssigned', (data) => {
  console.log(`Agent ${data.agentName} (${data.agentId}) joined the chat`);
});

5. MQTT (IoT Devices)

Order Status Updates

Python Example (paho-mqtt):
import paho.mqtt.client as mqtt
import json
import ssl

# MQTT callbacks
def on_connect(client, userdata, flags, rc):
    if rc == 0:
        print("Connected to MQTT broker")
        # Subscribe to order status updates
        client.subscribe("orders/+/status")
        print("Subscribed to order status updates")
    else:
        print(f"Connection failed with code {rc}")

def on_message(client, userdata, msg):
    print(f"Topic: {msg.topic}")
    payload = json.loads(msg.payload.decode())
    print(f"Order {payload['orderId']} status: {payload['status']}")
    print(f"Timestamp: {payload['timestamp']}")

# Create MQTT client
client = mqtt.Client(client_id="petstore-iot-device-001", protocol=mqtt.MQTTv5)

# Set authentication
client.username_pw_set("YOUR_USERNAME", "YOUR_PASSWORD")

# Enable TLS/SSL
client.tls_set(ca_certs=None, certfile=None, keyfile=None,
               cert_reqs=ssl.CERT_REQUIRED, tls_version=ssl.PROTOCOL_TLS)

# Set callbacks
client.on_connect = on_connect
client.on_message = on_message

# Connect to broker
client.connect("mqtt.petstoreapi.com", 8883, 60)

# Start loop
client.loop_forever()
JavaScript Example (MQTT.js):
const mqtt = require('mqtt');

// Connect to MQTT broker
const client = mqtt.connect('mqtts://mqtt.petstoreapi.com:8883', {
  clientId: 'petstore-iot-device-001',
  username: 'YOUR_USERNAME',
  password: 'YOUR_PASSWORD',
  protocol: 'mqtts',
  protocolVersion: 5,
  clean: true,
  keepalive: 60
});

client.on('connect', () => {
  console.log('Connected to MQTT broker');

  // Subscribe to order status updates
  client.subscribe('orders/+/status', { qos: 1 }, (err) => {
    if (!err) {
      console.log('Subscribed to order status updates');
    }
  });

  // Subscribe to payment notifications
  client.subscribe('payments/+/status', { qos: 1 }, (err) => {
    if (!err) {
      console.log('Subscribed to payment notifications');
    }
  });
});

client.on('message', (topic, message) => {
  const payload = JSON.parse(message.toString());
  console.log(`Topic: ${topic}`);
  console.log('Payload:', payload);

  if (topic.startsWith('orders/')) {
    console.log(`Order ${payload.orderId} is now ${payload.status}`);
  } else if (topic.startsWith('payments/')) {
    console.log(`Payment ${payload.paymentId} status: ${payload.status}`);
  }
});

client.on('error', (error) => {
  console.error('MQTT error:', error);
});

Authentication

All authenticated endpoints require either OAuth 2.0 or Bearer Token (JWT) authentication.

Getting an Access Token

# Example: Login to get Bearer token
curl -X POST https://api.petstoreapi.com/v1/login \
  -H "Content-Type: application/json" \
  -d '{
    "username": "your_username",
    "password": "your_password"
  }'
Response:
{
  "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "tokenType": "Bearer",
  "expiresIn": 3600,
  "refreshToken": "refresh_token_here",
  "user": {
    "id": "019b4137-6d8e-5c2b-e9f4-a3b5c8d7e2f1",
    "username": "your_username",
    "email": "[email protected]"
  }
}

Using the Token

Include the token in the Authorization header:
curl https://api.petstoreapi.com/v1/pets \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

Multi-Tenancy

Isolate your data using the X-Tenant-ID header:
curl https://api.petstoreapi.com/v1/pets \
  -H "X-Tenant-ID: 550e8400-e29b-41d4-a716-446655440000" \
  -H "Authorization: Bearer YOUR_TOKEN"
Important:
  • The tenant ID must be a valid UUID (v4 or v7)
  • Use the same tenant ID consistently for all related operations
  • Without a tenant ID, data is shared across all users

Rate Limits

The API uses IETF standard rate limiting headers:
RateLimit-Limit: 100
RateLimit-Remaining: 95
RateLimit-Reset: 1640000000
When you exceed the rate limit, you’ll receive a 429 Too Many Requests response:
{
  "type": "https://petstoreapi.com/errors/rate-limit-exceeded",
  "title": "Rate Limit Exceeded",
  "status": 429,
  "detail": "You have exceeded the rate limit of 100 requests per minute",
  "instance": "/v1/pets"
}

Error Handling

All errors follow RFC 9457 Problem Details format:
{
  "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"
    },
    {
      "field": "species",
      "message": "Must be one of: DOG, CAT, RABBIT, BIRD, REPTILE, OTHER",
      "code": "INVALID_ENUM_VALUE"
    }
  ]
}

Next Steps


Common Use Cases

Browse Available Pets

curl "https://api.petstoreapi.com/v1/pets?status=AVAILABLE&page=1&limit=20"

Get Pet Details

curl https://api.petstoreapi.com/v1/pets/019b4132-70aa-764f-b315-e2803d882a24

Create an Adoption Application

curl -X POST https://api.petstoreapi.com/v1/adoptions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -d '{
    "petId": "019b4132-70aa-764f-b315-e2803d882a24",
    "applicant": {
      "userId": "019b4137-6d8e-5c2b-e9f4-a3b5c8d7e2f1",
      "housingSituation": "HOUSE_WITH_YARD",
      "hasPets": true,
      "experience": "I have owned dogs for 10 years"
    }
  }'

Chat with AI Pet Advisor

curl -N -X POST https://api.petstoreapi.com/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -d '{
    "messages": [
      {
        "role": "USER",
        "content": "What breed of dog is best for apartment living?"
      }
    ],
    "model": "PET_ADVISOR_1",
    "stream": true
  }'

Ready to build something amazing? Start exploring the Modern Petstore API today!