Spec Template Examples for Modern Dev Teams
A template earns its place by reducing decision fatigue during delivery, not by adding ceremony. These examples are designed for real engineering reviews.
Quick answer
Strong spec templates share one property: they force explicit decisions early. At minimum, define goal, non-goals, acceptance criteria, edge cases, contract impacts, and rollout plan. This keeps scope stable when implementation pressure rises.
What a practical template must solve
- Prevent hidden scope expansion during implementation.
- Turn vague language into testable outcomes.
- Expose cross-team dependencies before coding starts.
- Capture risk and rollback behavior for production safety.
Three templates, three use cases
- Feature Spec: business behavior, boundaries, acceptance and edge cases.
- API Spec: request/response schema, errors, compatibility, idempotency.
- DB Spec: fields, constraints, indexes, migration and rollback strategy.
Most delivery work touches more than one template. Link them instead of duplicating requirements text.
Example: lightweight but complete feature spec
# Feature Spec: Contact Deduplication ## Goal - Prevent duplicate contacts by normalized email within a tenant. ## Non-goals - No historical record merge in this release. - No cross-tenant dedupe workflow. ## Acceptance Criteria - Given duplicate active emails in one tenant When dedupe job runs Then keep latest updated_at record and mark others merged - Given null or invalid email When dedupe job scans records Then record is skipped and reported in audit output ## Edge Cases - Same updated_at timestamp -> tie-break by max id - Concurrent writes during dedupe -> optimistic lock retry - Unauthorized manual dedupe request -> 403 ## Deliverables - Service job update - Audit log schema extension - Regression + integration tests - Rollback procedure for merge marks
Common template mistakes
- Listing implementation tasks without acceptance criteria.
- Writing "handle edge cases" without naming any edge case.
- Combining multiple behaviors into one acceptance bullet.
- Skipping rollback notes for stateful changes.
If a reviewer can't derive test cases from your template in under five minutes, it's still incomplete.
API spec example: webhook delivery endpoint
The feature spec example above shows behavioral scope. An API spec example shows a different layer: the contract between producer and consumer. Where the feature spec defines what the user experiences, the API spec defines what the integration layer guarantees.
# API Spec: POST /v1/webhooks/ingest
## Endpoint Contract
- Method: POST
- Auth: HMAC-SHA256 signature in X-Signature header
- Content-Type: application/json
## Request Schema
- event_type: string, required, enum: [order.created, order.shipped, order.cancelled]
- event_id: string, required, UUID v4, used for idempotency
- payload: object, required, shape varies by event_type
- timestamp: string, required, ISO 8601, UTC
## Response Contract
- 200: { received: true, event_id } — event accepted and queued
- 400: validation error envelope — malformed body or missing required field
- 401: signature mismatch — request rejected, no processing
- 409: { event_id, status: "duplicate" } — idempotent response, no reprocessing
## Compatibility Rules
- event_type enum is append-only; new types added with 2-week notice
- payload schema is versioned per event_type; consumer must handle unknown fields
- HMAC algorithm upgrade requires parallel support window of 30 days
## Edge Cases
- event_id reused within 24h -> 409, idempotent response
- payload exceeds 64KB -> 413, rejected before processing
- signature valid, event_type unknown -> 400, logged for monitoring
DB spec example: user audit log table
Database specs are often skipped because schema changes look mechanical. But schema decisions — nullability, index strategy, retention policy, migration approach — have long-term consequences that cannot be reversed cheaply. A minimal DB spec documents these decisions before the migration is written.
# DB Spec: user_audit_log table ## Purpose Record every state change on user accounts for compliance and incident review. ## Schema - id: bigint, auto-increment, primary key - user_id: bigint, not null, foreign key -> users.id (no cascade delete) - actor_id: bigint, nullable — null if system-initiated change - action: varchar(64), not null — enum: [created, updated, deactivated, deleted] - changed_fields: jsonb, nullable — field names and before/after values - created_at: timestamptz, not null, default now(), indexed ## Constraints - No updates or deletes allowed on this table (append-only by policy) - actor_id nullable to support system-initiated events without requiring a user record - changed_fields excludes password hashes and raw PII by application policy ## Migration - Additive schema change; no existing tables affected - Backfill: not required; log starts from migration date - Rollback: drop table; no data dependency on other tables ## Retention - Records retained 2 years per compliance policy - Archival job: monthly batch export to cold storage after 90 days - Purge: records older than 2 years deleted after archive confirmation
Choosing the right template for your change
Most changes touch multiple layers simultaneously — a new feature typically involves UI behavior, an API contract, and a database schema change. The question is not which template to use, but how to link them so that each layer's spec can be reviewed independently without losing the cross-layer dependencies.
Start with the feature spec as the top-level document. It defines the user-visible behavior and acceptance criteria, and all other specs are linked from it as dependencies. Add an API spec when the change introduces or modifies an endpoint, linking it to the specific acceptance criteria in the feature spec that require the endpoint behavior — reference the criteria rather than duplicating them. Add a DB spec when the change adds or alters a table, column, index, or constraint, including the migration approach and rollback procedure linked to the feature spec section that requires the data change. For cross-cutting features such as payments, use all three; a UI-only change may need only the feature spec, and a background job change may need only the feature and DB specs.
The linked spec structure means each reviewer can read exactly the layer they own without wading through irrelevant detail. It also means that when one layer changes during implementation, the impact on other layers is immediately visible — because the dependency is documented, not implicit.
Use these templates
Related articles
Editorial note
This guide covers Spec Template Examples for Modern Dev Teams for spec-first engineering teams. Examples are illustrative scenarios, not production code.
- Author details: Daniel Marsh
- Editorial policy: How we review and update articles
- Corrections: Contact the editor