Technical Specification

A document that defines exactly how software should behave — inputs, outputs, error cases, and constraints — in enough detail that a developer or AI agent can implement it without guessing.


What is a technical specification?

A technical specification (or “spec”) is a contract between intent and code. It takes the goals from a PRD (“users can browse instruments by category”) and translates them into precise, testable statements (“GET /api/instruments?category=tools returns a JSON array sorted alphabetically, paginated at 20”).

The spec does not describe the problem or the audience — that’s the PRD’s job. The spec describes external behaviour: what goes in, what comes out, and what happens when something goes wrong. It’s the technical translation layer between “what we want” and “what the code does.”

In AI-assisted development, specs are even more critical. Without one, an AI agent makes hundreds of small implementation decisions on its own. Some are fine. Many are wrong. A spec makes those decisions explicit and testable, so the agent executes against defined intent rather than inventing behaviour.

In plain terms

A spec is like a recipe with exact measurements. The PRD says “make chocolate cake for 8 people.” The spec says “200g flour, 150g sugar, bake at 180C for 25 minutes, the cake is done when a toothpick comes out clean.” Without the recipe, you get cake — but maybe not the cake you wanted.


At a glance


How does a technical specification work?

A good spec has six components. Each one eliminates a different category of guesswork.

1. Input format

What data does the system accept? Define every parameter: its name, type, whether it’s required or optional, valid values, and what happens with invalid input.

ParameterTypeRequiredValid values
localestringyes"en", "fr", "de", "it"
categorystringno"tools", "guides", "all"
pageintegerno>= 1, default 1

Think of it like...

An order form at a restaurant. Each field has a label, a format (number, text, checkbox), and some fields are required. If you leave the required fields blank, the kitchen sends it back.


2. Output format

What does the system return on success? Define the shape of the response — its structure, data types, sort order, and pagination.

{
  "data": [
    {
      "id": 42,
      "slug": "petition",
      "name": "Petition",
      "category": "tools",
      "description": "A formal request to..."
    }
  ],
  "meta": {
    "total": 156,
    "page": 1,
    "per_page": 20
  }
}

Be specific about defaults

“Sorted alphabetically” is better than “sorted.” “Paginated at 20 items per page” is better than “paginated.” Every ambiguity is a decision the implementer (or AI agent) makes for you.


3. Error cases

What happens when things go wrong? Define every expected failure mode and its response.

ConditionStatusResponse
Missing required param400{ "error": "locale is required" }
Invalid value400{ "error": "invalid category" }
Resource not found404{ "error": "not found" }
Empty result set200{ "data": [], "meta": { "total": 0 } }

Think of it like...

Error handling in a spec is like the “troubleshooting” section in an appliance manual. It doesn’t just say “the machine works.” It says “if the light blinks red, check X. If nothing happens, check Y.” Every predictable failure gets a defined response.

Concept to explore

See error-handling-spec for patterns and conventions around defining error behaviour in specs.


4. Invariants

What must always be true? Invariants are guarantees that hold regardless of input or state. They’re the “never break this” rules.

Examples:

  • “Every response includes a locale field matching the request”
  • “The total count is always accurate, even with filters applied”
  • “Timestamps are always in UTC ISO 8601 format”

Why invariants matter

Invariants are the most powerful part of a spec. They turn implicit assumptions (“of course dates are in UTC”) into explicit guarantees that can be tested automatically.


5. Constraints

What must never happen? Constraints are the negative-space counterpart of invariants — things the system must NOT do.

Examples:

  • “NEVER return data without translations in the requested locale”
  • “NEVER include internal IDs in public-facing responses”
  • “NEVER cache responses that depend on user-specific parameters”

Think of it like...

A doctor’s “do no harm” principle. The spec doesn’t just say what the system should do — it says what the system must never do. Constraints catch the AI agent’s well-intentioned but wrong shortcuts.


6. Acceptance criteria

How do we know it’s correct? Binary tests: given specific input, expect specific output. No interpretation needed.

GIVEN locale="fr" AND category="tools"
WHEN GET /api/instruments
THEN status is 200
AND body contains only French-language entries
AND body contains only items with category "tools"
AND results are sorted alphabetically by name

Binary means binary

An acceptance criterion either passes or fails. “The page loads quickly” is not binary. “The page loads in under 2 seconds” is. “The user experience is good” is not testable. “The user can complete the flow in 3 clicks or fewer” is.

Concept to explore

See acceptance-criteria for how to write criteria that are truly binary and testable.


Why do we use technical specifications?

Four problems a spec solves

1. Eliminates guessing. Without a spec, the implementer (human or AI) makes hundreds of small decisions about behaviour. With a spec, those decisions are made explicitly, once.

2. Makes testing possible. You can’t test against vague requirements. A spec gives you binary acceptance criteria that become automated tests directly.

3. Survives context resets. A prompt is gone after the session. A spec is version-controlled, persistent, and available to every future session. It’s the source of truth that outlives any single conversation.

4. Separates what from how. The PRD says “users can search for content.” The spec says “GET /api/search?q=term returns…” This separation means the PRD owner and the implementer can work in parallel with a clear contract between them.


When do we use technical specifications?

  • When implementing a feature or endpoint that has defined inputs and outputs
  • When working with AI coding agents — the spec is the most effective way to control agent behaviour
  • When a feature has edge cases or error conditions that need explicit handling
  • When multiple developers or sessions will touch the same feature over time
  • When you need to write automated tests — the spec becomes the test plan

Rule of thumb

If you’re about to tell an AI agent “build X” and X has more than one possible interpretation, write a spec first. The time spent writing it is always less than the time spent debugging wrong assumptions.


How can I think about it?

The architectural blueprint

A technical specification is like an architect’s blueprint.

  • The PRD is the client brief: “three-bedroom house, modern style, budget of 500K”
  • The spec is the blueprint: exact room dimensions, wall materials, door placements, electrical outlet positions
  • The builder (or AI agent) follows the blueprint exactly
  • If the blueprint says “window here,” you get a window there — the builder doesn’t decide to add an extra door instead
  • Ambiguity in the blueprint means the builder improvises, and improvisation means rework

The better the blueprint, the fewer surprises on site.

The music score

A spec is like a musical score for an orchestra.

  • The PRD is the composer’s intent: “a triumphant symphony in D major, 12 minutes long”
  • The spec is the score: every note, every dynamic marking, every tempo change, written precisely
  • The orchestra (or AI agent) performs from the score
  • Without the score, each musician interprets freely — you get noise, not music
  • With the score, every performance matches the composer’s intent, even if the orchestra has never met the composer

The spec lets the intent survive without the original author being present.


Concepts to explore next

ConceptWhat it coversStatus
acceptance-criteriaHow to define binary “done” conditionsstub
api-contractsHow to define the agreement between API provider and consumerstub
error-handling-specPatterns for defining error behaviour in specsstub
invariantsGuarantees that must always hold in a systemstub

Some of these cards don't exist yet

They’ll be created as the knowledge system grows. A broken link is a placeholder for future learning, not an error.


Check your understanding


Where this concept fits

Position in the knowledge graph

graph TD
    SD[Software Development] --> PR[Product Requirements]
    PR --> PRD[PRD]
    PR --> TS[Technical Specification]
    PR --> ADR[Architecture Decision Records]
    TS --> AC[Acceptance Criteria]
    TS --> APIC[API Contracts]
    TS --> EH[Error Handling Spec]
    style TS fill:#4a9ede,color:#fff

Related concepts:

  • spec-driven-development — the methodology where specs are the source of truth; the spec drives both code and tests
  • architecture-decision-records — ADRs capture why a certain spec approach was chosen over alternatives
  • apis — most specs define API behaviour; the spec is the formal version of the API contract

Further reading

Resources