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, notPOST /createOrder. Resource paths name things, never actions. - Kebab-case for multi-word resources.
/order-historyrather than/orderHistoryor/order_history— lowercase hyphenated segments are the most URL-friendly and the easiest to read. - Sub-resources as path segments.
/customers/1/addressesmodels 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:
| Style | Where | Example |
|---|---|---|
| kebab-case | URL paths | /payment-methods |
| camelCase | JSON fields (most common) | "paymentMethod" |
| snake_case | JSON 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.
productIdandcategoryNamebeatprodIdandcatName. Abbreviations save keystrokes and cost comprehension. - One term, one meaning. If
idmeans 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 bareactivethat could be a timestamp or a status string. - Timestamps carry their unit.
createdAtin 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.createdwithOrderCreatedororder_createdin 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.