Why Shouldn't You Use Verbs in REST API URLs?

Action verbs in REST API URLs violate fundamental REST principles and create maintenance nightmares. Learn why resource-oriented URLs are better and how Modern PetstoreAPI implements this correctly.

Ashley Innocent

Ashley Innocent

13 March 2026

Why Shouldn't You Use Verbs in REST API URLs?

TL;DR

REST API URLs should contain nouns (resources), not verbs (actions). HTTP methods (GET, POST, PUT, DELETE) are the verbs. Using action verbs like /getUser or /createOrder violates REST principles, creates inconsistency, and makes APIs harder to maintain. Modern PetstoreAPI uses resource-oriented URLs throughout.

Introduction

You’re designing an API endpoint to search for pets by status. Your first instinct might be: GET /findPetsByStatus?status=available. It’s descriptive, clear, and tells you exactly what it does. It’s also wrong.

REST APIs should use nouns in URLs, not verbs. The HTTP method is the verb. GET /pets?status=available is the correct design. The URL represents the resource (pets), and the method represents the action (get).

The old Swagger Petstore made this mistake with endpoints like /pet/findByStatus and /pet/findByTags. These action verbs in URLs violate REST principles and create maintenance problems. Modern PetstoreAPI fixes this by using resource-oriented URLs consistently.

💡
If you’re building or testing REST APIs, Apidog helps you validate URL design, test endpoint behavior, and ensure your API follows REST conventions. You can import OpenAPI specs, check for verb usage in URLs, and catch design issues early.
button

In this guide, you’ll learn why verbs don’t belong in REST URLs, how to design resource-oriented endpoints, and how Modern PetstoreAPI implements this correctly.

The Verb Problem in REST APIs

Action verbs in URLs indicate you’re thinking in RPC (Remote Procedure Call) terms, not REST terms.

RPC-Style URLs (Wrong)

POST /createUser
GET /getUser?id=123
PUT /updateUser
DELETE /deleteUser?id=123
GET /findUsersByRole?role=admin
POST /sendEmail
GET /calculateTotal

These URLs describe actions. They read like function calls: createUser(), getUser(), sendEmail().

REST-Style URLs (Correct)

POST /users
GET /users/123
PUT /users/123
DELETE /users/123
GET /users?role=admin
POST /emails
GET /orders/123/total

These URLs describe resources. The HTTP method provides the action.

Why This Matters

Consistency: REST URLs follow a predictable pattern. Once you know the resource name, you know all the endpoints:

With verb-based URLs, every endpoint is unique. There’s no pattern to follow.

Scalability: As your API grows, verb-based URLs multiply:

Resource-oriented URLs use query parameters:

One endpoint handles all filtering.

Why HTTP Methods Are the Verbs

REST leverages HTTP’s built-in verbs. You don’t need to invent your own.

HTTP Methods Map to CRUD Operations

POST   → Create
GET    → Read
PUT    → Update (replace)
PATCH  → Update (partial)
DELETE → Delete

These methods have defined semantics. GET is safe and idempotent. POST creates resources. DELETE removes them.

Example: User Management

Wrong (verbs in URLs):

POST /createUser
GET /getUser?id=123
POST /updateUser
POST /deleteUser

Every operation uses a different URL. The HTTP method doesn’t convey meaning.

Correct (HTTP methods as verbs):

POST /users           ← Create user
GET /users/123        ← Get user
PUT /users/123        ← Update user
DELETE /users/123     ← Delete user

The URL stays the same. The method changes.

Benefits of Using HTTP Methods

1. Caching: GET requests can be cached. Browsers and proxies know this. If you use POST /getUser, caching breaks.

2. Idempotency: PUT and DELETE are idempotent. Calling them multiple times has the same effect as calling once. This matters for retry logic.

3. Safety: GET is safe—it doesn’t modify state. Tools and crawlers can safely call GET endpoints.

4. Standards Compliance: HTTP clients, proxies, and caches understand HTTP methods. They don’t understand your custom verbs.

Real Examples from Swagger Petstore

The old Swagger Petstore includes several verb-based endpoints.

Example 1: Finding Pets by Status

Swagger Petstore (Wrong):

GET /pet/findByStatus?status=available

Problems:

Modern PetstoreAPI (Correct):

GET /pets?status=AVAILABLE

Benefits:

See the Modern PetstoreAPI REST documentation for the complete implementation.

Example 2: Finding Pets by Tags

Swagger Petstore (Wrong):

GET /pet/findByTags?tags=tag1,tag2

Modern PetstoreAPI (Correct):

GET /pets?tags=friendly,trained

Example 3: User Login

Swagger Petstore (Wrong):

GET /user/login?username=john&password=secret

Multiple problems:

Modern PetstoreAPI (Correct):

POST /auth/login
Content-Type: application/json

{
  "username": "john",
  "password": "secret123"
}

Benefits:

How Modern PetstoreAPI Fixes This

Modern PetstoreAPI uses resource-oriented URLs throughout.

Pet Management

GET /pets                    ← List all pets
GET /pets?status=AVAILABLE   ← Filter by status
GET /pets?species=dog        ← Filter by species
GET /pets/{id}               ← Get specific pet
POST /pets                   ← Create new pet
PUT /pets/{id}               ← Update pet
PATCH /pets/{id}             ← Partial update
DELETE /pets/{id}            ← Delete pet

No verbs. Just resources and HTTP methods.

Order Management

GET /orders                  ← List orders
GET /orders/{id}             ← Get order
POST /orders                 ← Create order
PUT /orders/{id}             ← Update order
DELETE /orders/{id}          ← Cancel order
GET /orders/{id}/items       ← Get order items

Complex Operations

For operations that don’t map cleanly to CRUD, Modern PetstoreAPI uses sub-resources:

POST /orders/{id}/payment    ← Process payment for order
POST /orders/{id}/shipment   ← Create shipment for order
POST /pets/{id}/adoption     ← Start adoption process

These are still resource-oriented. /orders/{id}/payment represents the payment resource for an order.

When Verbs Seem Necessary

Some operations don’t fit the CRUD model. Here’s how to handle them without verbs in URLs.

Search Operations

Wrong:

GET /searchPets?query=labrador

Correct Option 1 (Query Parameters):

GET /pets?search=labrador

Correct Option 2 (Search Resource):

GET /pets/search?q=labrador

Correct Option 3 (QUERY Method):

QUERY /pets
Content-Type: application/json

{
  "query": "labrador",
  "filters": {
    "status": "AVAILABLE"
  }
}

Modern PetstoreAPI supports all three patterns depending on complexity.

Calculations

Wrong:

GET /calculateShipping?weight=10&destination=NY

Correct:

GET /shipping-estimates?weight=10&destination=NY

The resource is “shipping estimates,” not the calculation action.

Batch Operations

Wrong:

POST /batchDeletePets

Correct:

DELETE /pets?ids=1,2,3

Or use a batch resource:

POST /pets/batch-operations
Content-Type: application/json

{
  "operation": "delete",
  "ids": [1, 2, 3]
}

Actions That Change State

Wrong:

POST /activateUser
POST /deactivateUser

Correct:

PATCH /users/{id}
Content-Type: application/json

{
  "status": "ACTIVE"
}

State changes are updates to the resource.

Testing URL Design with Apidog

Apidog helps you validate REST API design and catch verb usage in URLs.

Import Modern PetstoreAPI

  1. Import the Modern PetstoreAPI OpenAPI spec
  2. Apidog automatically generates test cases
  3. Review endpoint structure and naming

Check for Verbs in URLs

Create a custom validation rule in Apidog:

// Check if URL contains common action verbs
const verbs = ['get', 'create', 'update', 'delete', 'find', 'search',
               'calculate', 'process', 'send', 'fetch'];
const url = request.url.toLowerCase();

for (const verb of verbs) {
  if (url.includes(`/${verb}`)) {
    throw new Error(`URL contains verb: ${verb}. Use resource-oriented URLs instead.`);
  }
}

Test Endpoint Consistency

Apidog can verify that related endpoints follow consistent patterns:

✓ GET /pets
✓ POST /pets
✓ GET /pets/{id}
✓ PUT /pets/{id}
✓ DELETE /pets/{id}

All use the same base resource (/pets).

Compare Against Modern PetstoreAPI

Use Modern PetstoreAPI as a reference:

  1. Import both your API and Modern PetstoreAPI into Apidog
  2. Compare endpoint structures side-by-side
  3. Identify inconsistencies and verb usage
  4. Refactor your API to match REST principles

Migration Strategies

If you have an existing API with verbs in URLs, here’s how to migrate.

Strategy 1: Versioning

Create a new API version with correct URLs:

# Old API (v1)
GET /api/v1/findPetsByStatus?status=available

# New API (v2)
GET /api/v2/pets?status=available

Maintain v1 for backward compatibility, encourage migration to v2.

Strategy 2: Aliasing

Support both old and new URLs temporarily:

# Old URL (deprecated)
GET /pet/findByStatus?status=available

# New URL (preferred)
GET /pets?status=available

Return deprecation warnings in responses:

{
  "data": [...],
  "warnings": [
    {
      "code": "DEPRECATED_ENDPOINT",
      "message": "This endpoint is deprecated. Use GET /pets?status=available instead.",
      "sunset": "2027-01-01"
    }
  ]
}

Strategy 3: Redirects

Use HTTP 301 redirects for simple migrations:

GET /pet/findByStatus?status=available
→ 301 Moved Permanently
Location: /pets?status=available

This works for GET requests but not for POST, PUT, or DELETE.

Conclusion

REST API URLs should contain nouns (resources), not verbs (actions). HTTP methods provide the verbs. This principle creates consistent, scalable, and maintainable APIs.

The old Swagger Petstore violated this with endpoints like /pet/findByStatus. Modern PetstoreAPI fixes this by using resource-oriented URLs throughout: /pets?status=AVAILABLE.

Key takeaways:

Check out the Modern PetstoreAPI documentation for complete examples of resource-oriented URL design.

FAQ

Can I ever use verbs in REST URLs?

Rarely. If an operation truly doesn’t fit the resource model (like /search or /login), a verb might be acceptable. But 95% of the time, you can model it as a resource.

What about /login and /logout?

These are common exceptions. Many APIs use /auth/login and /auth/logout. Alternatively, model them as resources: POST /sessions (login) and DELETE /sessions/{id} (logout).

How do I handle complex queries?

Use query parameters for simple filtering: /pets?status=available&species=dog. For complex queries, use the QUERY HTTP method or a search resource: POST /pets/search.

What if my operation doesn’t map to CRUD?

Model it as a sub-resource. Instead of POST /processPayment, use POST /orders/{id}/payment. The payment is a resource related to the order.

How do I test if my URLs are resource-oriented?

Use Apidog to import your OpenAPI spec and check for verbs in URLs. Compare your API structure against Modern PetstoreAPI as a reference.

Should I use /pets/search or /pets?search=query?

Both are acceptable. /pets?search=query is simpler for basic search. /pets/search or QUERY /pets works better for complex search with multiple parameters.

How do I migrate from verb-based URLs?

Use API versioning (/v2/pets instead of /v1/findPets), add deprecation warnings, and give clients time to migrate. See the Migration Strategies section for details.

Does Modern PetstoreAPI use any verbs in URLs?

Modern PetstoreAPI avoids verbs in URLs. Operations like search, filter, and authentication are modeled as resources or use query parameters. Check the REST API documentation for examples.

Explore more

What is Tokenization? The Ultimate Guide to API Security

What is Tokenization? The Ultimate Guide to API Security

Tokenization is a powerful method to secure sensitive data by replacing it with non-sensitive tokens. In this guide, we explore the core concepts of tokenization, compare it with encryption, review key benefits and use cases, and show how to design and test secure APIs using Apidog.

13 March 2026

How Do You Build Event-Driven APIs with Webhooks and Message Queues?

How Do You Build Event-Driven APIs with Webhooks and Message Queues?

Event-driven APIs decouple services and enable asynchronous processing. Learn how to combine webhooks, message queues, and event buses with Modern PetstoreAPI patterns.

13 March 2026

How Do You Stream API Responses Using Server-Sent Events (SSE)?

How Do You Stream API Responses Using Server-Sent Events (SSE)?

Server-Sent Events let you stream API responses in real-time. Learn how to implement SSE for live updates, AI streaming, and progress tracking with Modern PetstoreAPI examples.

13 March 2026

Practice API Design-first in Apidog

Discover an easier way to build and use APIs