REST API Examples

Real-world REST API patterns with complete request and response examples

Users API

Complete CRUD operations for user management. Links follow HATEOAS conventions and CQRS read model patterns conventions.

List Users with Pagination

GET /api/v1/users?page=1&limit=10&status=active

Headers:

Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
Accept: application/json

Response (200 OK):

{
  "data": [
    {
      "id": 1,
      "name": "John Doe",
      "email": "john@example.com",
      "role": "admin",
      "status": "active",
      "avatar_url": "https://api.example.com/avatars/1.jpg",
      "created_at": "2023-01-15T10:30:00Z",
      "updated_at": "2023-06-20T14:00:00Z"
    },
    {
      "id": 2,
      "name": "Jane Smith",
      "email": "jane@example.com",
      "role": "user",
      "status": "active",
      "avatar_url": null,
      "created_at": "2023-02-20T08:15:00Z",
      "updated_at": "2023-02-20T08:15:00Z"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 10,
    "total": 150,
    "total_pages": 15,
    "has_next": true,
    "has_prev": false
  },
  "links": {
    "self": "/api/v1/users?page=1&limit=10&status=active",
    "next": "/api/v1/users?page=2&limit=10&status=active",
    "last": "/api/v1/users?page=15&limit=10&status=active"
  }
}

Get Single User

GET /api/v1/users/123

Response (200 OK):

{
  "data": {
    "id": 123,
    "name": "John Doe",
    "email": "john@example.com",
    "role": "admin",
    "status": "active",
    "avatar_url": "https://api.example.com/avatars/123.jpg",
    "profile": {
      "bio": "Software developer and API enthusiast",
      "location": "San Francisco, CA",
      "website": "https://johndoe.dev"
    },
    "created_at": "2023-01-15T10:30:00Z",
    "updated_at": "2023-06-20T14:00:00Z"
  }
}

Response (404 Not Found):

{
  "error": {
    "code": "USER_NOT_FOUND",
    "message": "User with ID 999 not found",
    "request_id": "req_abc123"
  }
}

Create User

POST /api/v1/users

Headers:

Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
Content-Type: application/json

Request Body:

{
  "name": "Alice Johnson",
  "email": "alice@example.com",
  "password": "SecureP@ssw0rd!",
  "role": "user",
  "profile": {
    "bio": "New to the platform",
    "location": "New York, NY"
  }
}

Response (201 Created):

HTTP/1.1 201 Created
Location: /api/v1/users/124

{
  "data": {
    "id": 124,
    "name": "Alice Johnson",
    "email": "alice@example.com",
    "role": "user",
    "status": "pending_verification",
    "profile": {
      "bio": "New to the platform",
      "location": "New York, NY"
    },
    "created_at": "2023-06-21T09:00:00Z"
  }
}

Response (422 Unprocessable Entity):

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Validation failed",
    "details": [
      {
        "field": "email",
        "code": "ALREADY_EXISTS",
        "message": "This email is already registered"
      },
      {
        "field": "password",
        "code": "TOO_WEAK",
        "message": "Password must contain at least one uppercase letter"
      }
    ]
  }
}

Update User (Partial)

PATCH /api/v1/users/123

Request Body:

{
  "name": "John D. Doe",
  "profile": {
    "bio": "Senior software developer and API enthusiast"
  }
}

Response (200 OK):

{
  "data": {
    "id": 123,
    "name": "John D. Doe",
    "email": "john@example.com",
    "profile": {
      "bio": "Senior software developer and API enthusiast",
      "location": "San Francisco, CA",
      "website": "https://johndoe.dev"
    },
    "updated_at": "2023-06-21T10:00:00Z"
  }
}

Delete User

DELETE /api/v1/users/123

Response (204 No Content):

HTTP/1.1 204 No Content
// Empty body

Products API

E-commerce product management with filtering and search.

Search Products with Filters

GET /api/v1/products?category=electronics&price_min=50&price_max=500&sort=-rating&in_stock=true

Response (200 OK):

{
  "data": [
    {
      "id": 456,
      "name": "Wireless Bluetooth Headphones",
      "slug": "wireless-bluetooth-headphones",
      "description": "Premium noise-canceling wireless headphones",
      "price": 199.99,
      "currency": "USD",
      "category": {
        "id": 10,
        "name": "Electronics",
        "slug": "electronics"
      },
      "images": [
        {
          "url": "https://cdn.example.com/products/456/main.jpg",
          "alt": "Headphones front view",
          "is_primary": true
        },
        {
          "url": "https://cdn.example.com/products/456/side.jpg",
          "alt": "Headphones side view",
          "is_primary": false
        }
      ],
      "attributes": {
        "color": "Black",
        "brand": "AudioTech",
        "battery_life": "30 hours"
      },
      "stock": {
        "quantity": 150,
        "in_stock": true,
        "low_stock_threshold": 20
      },
      "rating": {
        "average": 4.7,
        "count": 1250
      },
      "created_at": "2023-03-10T12:00:00Z"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 45
  },
  "filters_applied": {
    "category": "electronics",
    "price_range": {"min": 50, "max": 500},
    "in_stock": true
  }
}

Create Product

POST /api/v1/products

Request Body:

{
  "name": "Smart Watch Pro",
  "description": "Advanced fitness tracking smartwatch",
  "price": 299.99,
  "currency": "USD",
  "category_id": 10,
  "sku": "SW-PRO-001",
  "attributes": {
    "color": "Silver",
    "brand": "TechTime",
    "water_resistance": "50m"
  },
  "stock": {
    "quantity": 500,
    "low_stock_threshold": 50
  }
}

Response (201 Created):

{
  "data": {
    "id": 789,
    "name": "Smart Watch Pro",
    "slug": "smart-watch-pro",
    "sku": "SW-PRO-001",
    "price": 299.99,
    "currency": "USD",
    "status": "draft",
    "created_at": "2023-06-21T11:00:00Z"
  }
}

Orders API

Order management with nested resources and state transitions.

Create Order

POST /api/v1/orders

Request Body:

{
  "items": [
    {
      "product_id": 456,
      "quantity": 2,
      "variant_id": "color-black"
    },
    {
      "product_id": 789,
      "quantity": 1
    }
  ],
  "shipping_address": {
    "name": "John Doe",
    "line1": "123 Main Street",
    "line2": "Apt 4B",
    "city": "San Francisco",
    "state": "CA",
    "postal_code": "94102",
    "country": "US",
    "phone": "+1-555-123-4567"
  },
  "billing_address_same_as_shipping": true,
  "payment_method_id": "pm_card_visa",
  "coupon_code": "SAVE20"
}

Response (201 Created):

{
  "data": {
    "id": "ord_abc123def456",
    "order_number": "ORD-2023-001234",
    "status": "pending_payment",
    "items": [
      {
        "id": "item_001",
        "product_id": 456,
        "product_name": "Wireless Bluetooth Headphones",
        "quantity": 2,
        "unit_price": 199.99,
        "subtotal": 399.98
      },
      {
        "id": "item_002",
        "product_id": 789,
        "product_name": "Smart Watch Pro",
        "quantity": 1,
        "unit_price": 299.99,
        "subtotal": 299.99
      }
    ],
    "subtotal": 699.97,
    "discount": {
      "code": "SAVE20",
      "amount": 139.99,
      "type": "percentage",
      "value": 20
    },
    "shipping": {
      "method": "standard",
      "cost": 9.99,
      "estimated_delivery": "2023-06-28"
    },
    "tax": 44.80,
    "total": 614.77,
    "currency": "USD",
    "payment_status": "pending",
    "created_at": "2023-06-21T12:00:00Z"
  },
  "links": {
    "self": "/api/v1/orders/ord_abc123def456",
    "payment": "/api/v1/orders/ord_abc123def456/pay"
  }
}

Get Order with Items

GET /api/v1/orders/ord_abc123def456?include=items,shipping

Response (200 OK):

{
  "data": {
    "id": "ord_abc123def456",
    "order_number": "ORD-2023-001234",
    "status": "shipped",
    "items": [...],
    "shipping": {
      "method": "standard",
      "carrier": "FedEx",
      "tracking_number": "1234567890",
      "tracking_url": "https://fedex.com/track/1234567890",
      "shipped_at": "2023-06-22T09:00:00Z",
      "estimated_delivery": "2023-06-28"
    },
    "timeline": [
      {"status": "created", "at": "2023-06-21T12:00:00Z"},
      {"status": "paid", "at": "2023-06-21T12:05:00Z"},
      {"status": "processing", "at": "2023-06-21T14:00:00Z"},
      {"status": "shipped", "at": "2023-06-22T09:00:00Z"}
    ]
  }
}

Cancel Order

POST /api/v1/orders/ord_abc123def456/cancel

Request Body:

{
  "reason": "Changed my mind",
  "refund_to_original_payment": true
}

Response (200 OK):

{
  "data": {
    "id": "ord_abc123def456",
    "status": "cancelled",
    "cancellation": {
      "reason": "Changed my mind",
      "cancelled_at": "2023-06-21T13:00:00Z",
      "refund": {
        "id": "ref_xyz789",
        "amount": 614.77,
        "status": "processing",
        "estimated_completion": "2023-06-24"
      }
    }
  }
}

Response (409 Conflict - Order already shipped):

{
  "error": {
    "code": "ORDER_CANNOT_BE_CANCELLED",
    "message": "Order has already been shipped and cannot be cancelled",
    "suggestion": "Please initiate a return instead",
    "links": {
      "return": "/api/v1/orders/ord_abc123def456/return"
    }
  }
}

Authentication API

User authentication with JWT tokens.

Login

POST /api/v1/auth/login

Request Body:

{
  "email": "john@example.com",
  "password": "SecureP@ssw0rd!"
}

Response (200 OK):

{
  "data": {
    "user": {
      "id": 123,
      "name": "John Doe",
      "email": "john@example.com",
      "role": "admin"
    },
    "tokens": {
      "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
      "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
      "token_type": "Bearer",
      "expires_in": 3600
    }
  }
}

Response (401 Unauthorized):

{
  "error": {
    "code": "INVALID_CREDENTIALS",
    "message": "Email or password is incorrect"
  }
}

Refresh Token

POST /api/v1/auth/refresh

Request Body:

{
  "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

Response (200 OK):

{
  "data": {
    "tokens": {
      "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
      "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
      "token_type": "Bearer",
      "expires_in": 3600
    }
  }
}

Register

POST /api/v1/auth/register

Request Body:

{
  "name": "New User",
  "email": "newuser@example.com",
  "password": "SecureP@ssw0rd!",
  "password_confirmation": "SecureP@ssw0rd!",
  "terms_accepted": true
}

Response (201 Created):

{
  "data": {
    "user": {
      "id": 125,
      "name": "New User",
      "email": "newuser@example.com",
      "status": "pending_verification"
    },
    "message": "Please check your email to verify your account"
  }
}

Logout

POST /api/v1/auth/logout

Headers:

Authorization: Bearer eyJhbGciOiJIUzI1NiIs...

Response (204 No Content):

HTTP/1.1 204 No Content

File Upload API

Handling file uploads with multipart form data.

Upload File (Multipart)

POST /api/v1/files/upload

Headers:

Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary

Form Data:

------WebKitFormBoundary
Content-Disposition: form-data; name="file"; filename="document.pdf"
Content-Type: application/pdf

[binary file data]
------WebKitFormBoundary
Content-Disposition: form-data; name="folder"

documents
------WebKitFormBoundary--

Response (201 Created):

{
  "data": {
    "id": "file_abc123",
    "name": "document.pdf",
    "original_name": "document.pdf",
    "mime_type": "application/pdf",
    "size": 1048576,
    "size_human": "1 MB",
    "url": "https://cdn.example.com/files/documents/file_abc123.pdf",
    "folder": "documents",
    "uploaded_at": "2023-06-21T14:00:00Z"
  }
}

Get Presigned Upload URL

For large files, use presigned URLs to upload directly to cloud storage.

POST /api/v1/files/presign

Request Body:

{
  "filename": "large-video.mp4",
  "content_type": "video/mp4",
  "size": 104857600
}

Response (200 OK):

{
  "data": {
    "upload_url": "https://s3.amazonaws.com/bucket/...?X-Amz-Signature=...",
    "file_id": "file_xyz789",
    "expires_at": "2023-06-21T15:00:00Z",
    "instructions": {
      "method": "PUT",
      "headers": {
        "Content-Type": "video/mp4"
      }
    }
  }
}

Webhooks API

Managing webhook subscriptions for event notifications.

Create Webhook Subscription

POST /api/v1/webhooks

Request Body:

{
  "url": "https://your-server.com/webhooks/orders",
  "events": [
    "order.created",
    "order.paid",
    "order.shipped",
    "order.delivered",
    "order.cancelled"
  ],
  "secret": "whsec_your_webhook_secret"
}

Response (201 Created):

{
  "data": {
    "id": "wh_abc123",
    "url": "https://your-server.com/webhooks/orders",
    "events": [
      "order.created",
      "order.paid",
      "order.shipped",
      "order.delivered",
      "order.cancelled"
    ],
    "status": "active",
    "created_at": "2023-06-21T15:00:00Z"
  }
}

Webhook Payload Example

This is what your server will receive when events occur.

POST to your webhook URL:

POST /webhooks/orders HTTP/1.1
Host: your-server.com
Content-Type: application/json
X-Webhook-Signature: sha256=abc123...
X-Webhook-Event: order.shipped
X-Webhook-Delivery: del_xyz789

{
  "id": "evt_abc123",
  "type": "order.shipped",
  "created_at": "2023-06-22T09:00:00Z",
  "data": {
    "order": {
      "id": "ord_abc123def456",
      "order_number": "ORD-2023-001234",
      "status": "shipped",
      "tracking_number": "1234567890"
    }
  }
}