API naming conventions

Product names get the glory, but the names inside your API — resources, endpoints, fields — decide whether developers enjoy using it. These are the conventions the REST community has largely converged on.

Resources and URLs

The dominant convention is plural nouns for collections: /users for the collection, /users/451 for one member. It reads naturally and stays consistent whether you address one item or many.

  • No verbs in URLs. The HTTP method is the verb: POST /orders, not POST /createOrder. Resource paths name things, never actions.
  • Kebab-case for multi-word resources. /order-history rather than /orderHistory or /order_history — lowercase hyphenated segments are the most URL-friendly and the easiest to read.
  • Sub-resources as path segments. /customers/1/addresses models hierarchy directly in the path instead of inventing new top-level concepts.

Casing rules

Pick one casing and never mix it. The two serious candidates:

StyleWhereExample
kebab-caseURL paths/payment-methods
camelCaseJSON fields (most common)"paymentMethod"
snake_caseJSON fields (Python/Ruby shops)"payment_method"

camelCase dominates JSON APIs because most code generators and client libraries expect it. Whatever you choose, document it in one place and lint for it — mixed casing is the fastest way to make an API feel amateur.

Versioning

Put the version in the URL path: /v1/orders. It is the most discoverable and debuggable scheme — the version is visible in logs, docs and browser address bars. Avoid versioning via headers for public APIs; it hides critical information from the people debugging at 2am.

Start at v1 on day one, even if it feels premature. Adding versioning later means either breaking existing clients or supporting two unversioned schemes forever.

Fields and parameters

  • Semantic names over abbreviations. productId and categoryName beat prodId and catName. Abbreviations save keystrokes and cost comprehension.
  • One term, one meaning. If id means the database row in one endpoint and the public identifier in another, rename one of them.
  • Boolean fields read as questions. isActive, hasTrial, canRefund — never a bare active that could be a timestamp or a status string.
  • Timestamps carry their unit. createdAt in ISO 8601, always UTC. Your future self debugging timezone bugs will be grateful.

Naming webhooks and events

Webhooks and events deserve the same discipline as REST resources. Use past-tense, dot-namespaced event names: order.created, payment.failed, user.deleted. The namespace (the resource) comes first so consumers can subscribe with prefixes, and past tense makes it obvious the thing already happened.

  • One naming scheme for all events. Do not mix order.created with OrderCreated or order_created in the same API — pick dot-namespaced lowercase and stick to it.
  • Version events like endpoints. An event schema is a contract too. Include a version field or namespace (v1.order.created) so you can evolve payloads without breaking subscribers silently.
  • Name the payload fields with the same casing as your REST responses. A consumer should not need two mental models for the same data.

Error names and codes

Machine-readable error identifiers are names as well. Use snake_case error codes that read like the problem: payment_declined, rate_limit_exceeded, invalid_api_key. Pair each with a human-readable message and a link to docs. Never expose stack traces or internal exception class names — they leak implementation details and confuse integrators.

SDK and package naming

When you ship client libraries, the package name extends the brand: syncforge-node, syncforge-python. Keep the product name first and the language or platform second, in lowercase with hyphens. Inside the SDK, mirror the API's resource names so documentation examples translate one-to-one between raw HTTP and the client library.

Naming the product itself?

Conventions cover the inside of the API. For the product name on the tin, use the generator and the step-by-step naming process.

Read the naming guide