Skip to main content
New: Forge AI docs + Loop PM assistant. 7-day free trial.
TemplateFREE⏱️ 90-120 minutes

API Design Specification Template

A structured API design spec template covering REST and GraphQL endpoints, versioning strategy, authentication, error handling, and pagination. Includes a filled example for a project management API.

By Tim Adair• Last updated 2026-03-04
API Design Specification Template preview

API Design Specification Template

Free API Design Specification Template — open and start using immediately

or use email

Instant access. No spam.

What This Template Is For

An API design specification defines the contract between your service and its consumers before any code is written. It captures endpoints, data shapes, authentication, error formats, versioning rules, and pagination patterns in a single document that frontend engineers, partner teams, and third-party developers can all build against.

Skipping the design phase leads to inconsistent naming, undocumented error codes, and breaking changes that force consumers to rewrite their integrations. A written spec prevents these problems by making every design decision reviewable and reversible before it becomes cemented in production code.

This template works for both REST APIs and GraphQL services. It is scoped to the API surface, not the underlying architecture. If you need to document database schemas, service dependencies, and rollout plans alongside your API, use the Technical Specification Template instead. For the broader context of how API design fits into the technical PM workflow, see the Technical PM Handbook.

If you are deciding whether to build an API feature, score it with the RICE Calculator first.


How to Use This Template

  1. Start after the product requirements are finalized but before backend implementation begins. The author should be the API owner or lead backend engineer.
  2. Define the resource model first. List every resource (noun) your API exposes and map the relationships between them. This becomes the foundation for endpoint design.
  3. Write endpoint contracts with enough detail for consumers to mock their integrations. Include request/response schemas, field types, required/optional annotations, and all status codes.
  4. Choose a versioning strategy and document it explicitly. Consumers need to know how you will handle breaking changes before they commit to integrating.
  5. Define the authentication model. Specify token types, scopes, and how API keys differ from user tokens.
  6. Document error responses with a consistent format. Every error should include a machine-readable code, a human-readable message, and a documentation link.
  7. Circulate the draft to frontend engineers, partner teams, and anyone who will consume the API. Use the Open Questions section for unresolved design decisions.

The Template

API Overview

FieldDetails
API Name[Name]
Version[v1, v2, etc.]
Base URL[https://api.example.com/v1]
Author[Engineer name]
Reviewers[Names]
Date[Date]
StatusDraft / In Review / Approved / Implemented

Summary. [1-2 sentences describing what this API does and who its primary consumers are.]

Design Principles.

  • RESTful resource naming (nouns, not verbs)
  • Consistent error response format across all endpoints
  • Pagination on all list endpoints
  • Idempotent write operations where possible
  • Backward-compatible changes by default

Versioning Strategy

DecisionValue
StrategyURL path (/v1/) / Header (Accept-Version) / Query param (?version=1)
Breaking Change Policy[How long old versions are supported after a new version ships]
Deprecation Notice Period[Minimum days/weeks before removal]
Sunset HeaderYes / No

What constitutes a breaking change:

  • Removing an endpoint
  • Removing or renaming a response field
  • Changing the type of an existing field
  • Adding a required request parameter
  • Changing authentication requirements

What is NOT a breaking change:

  • Adding a new optional request parameter
  • Adding a new response field
  • Adding a new endpoint
  • Adding a new error code

Authentication

PropertyValue
Auth TypeOAuth 2.0 / API Key / JWT / Bearer Token
Token LocationAuthorization header / Query param / Cookie
Token Lifetime[Duration]
Refresh Mechanism[How tokens are refreshed]
Scopes[List of scopes and what each permits]

Rate limits by auth type:

Auth TypeRequests/MinuteBurst Limit
API Key (free)[Limit][Burst]
API Key (paid)[Limit][Burst]
OAuth token[Limit][Burst]

Resource Model

ResourceDescriptionRelationships
[Resource 1][What it represents][Has many X, belongs to Y]
[Resource 2][What it represents][Has many X, belongs to Y]

Endpoints

[Resource]: [Method] [Path]

PropertyValue
MethodGET / POST / PUT / PATCH / DELETE
Path/v1/[resource]
AuthRequired / Optional / None
Scopes[Required scopes]
Rate Limit[Requests per minute]
IdempotentYes / No

Request body:

{
  "field_1": "string (required)",
  "field_2": 123,
  "field_3": true
}

Response (200/201):

{
  "id": "uuid",
  "field_1": "string",
  "created_at": "2026-03-04T00:00:00Z",
  "updated_at": "2026-03-04T00:00:00Z"
}

Error responses:

StatusCodeDescription
400VALIDATION_ERROR[When this occurs]
401UNAUTHORIZED[When this occurs]
403FORBIDDEN[When this occurs]
404NOT_FOUND[When this occurs]
409CONFLICT[When this occurs]
429RATE_LIMITED[When this occurs]

[Repeat for each endpoint]


Pagination

PropertyValue
StrategyCursor-based / Offset-based
Default Page Size[Number]
Max Page Size[Number]
Cursor Field[Field name]

Example response:

{
  "data": [],
  "pagination": {
    "cursor": "eyJpZCI6...",
    "has_more": true,
    "total_count": 142
  }
}

Error Format

All errors follow this structure:

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Human-readable description",
    "details": [
      { "field": "email", "issue": "Invalid email format" }
    ],
    "doc_url": "https://docs.example.com/errors/VALIDATION_ERROR"
  }
}

Open Questions

#QuestionOwnerStatusDecision
1[Question][Name]Open
2[Question][Name]Open

Filled Example: Project Management API v1

API Overview

FieldDetails
API NameTaskFlow API
Versionv1
Base URLhttps://api.taskflow.io/v1
AuthorJordan Park, Senior Backend Engineer
ReviewersLisa Tran (PM), Dev Patel (Frontend), Maya Santos (Partner Eng)
DateMarch 2026
StatusApproved

Summary. The TaskFlow API enables third-party integrations and internal clients to create, read, update, and manage projects, tasks, and team members. Primary consumers are the web/mobile frontend, Zapier integration, and 3 strategic partner applications.

Endpoints (excerpt)

Tasks: POST /v1/projects/:project_id/tasks

PropertyValue
MethodPOST
Path/v1/projects/:project_id/tasks
AuthRequired (Bearer token)
Scopestasks:write
Rate Limit120/min
IdempotentYes (via Idempotency-Key header)

Request body:

{
  "title": "Update onboarding flow (required)",
  "description": "Redesign the first-run experience based on user research findings",
  "assignee_id": "usr_7k2m9n",
  "priority": "high",
  "due_date": "2026-04-15",
  "labels": ["ux", "onboarding"]
}

Response (201):

{
  "id": "tsk_3a8b2c",
  "project_id": "prj_1x4y7z",
  "title": "Update onboarding flow",
  "description": "Redesign the first-run experience based on user research findings",
  "assignee": { "id": "usr_7k2m9n", "name": "Alex Rivera" },
  "priority": "high",
  "status": "todo",
  "due_date": "2026-04-15",
  "labels": ["ux", "onboarding"],
  "created_at": "2026-03-04T10:30:00Z",
  "updated_at": "2026-03-04T10:30:00Z"
}

Versioning Strategy

URL path versioning (/v1/). Breaking changes ship in a new version (/v2/). Previous versions are supported for 12 months after the new version launches. A Sunset response header is added to deprecated version responses 90 days before end-of-life. Non-breaking additions (new fields, new endpoints) ship within the current version without a version bump.

Key Takeaways

  • Define the resource model and relationships before writing any endpoint contracts
  • Choose a versioning strategy and document what constitutes a breaking change
  • Use a consistent error format with machine-readable codes and documentation links
  • Design pagination into every list endpoint from the start
  • Circulate the spec to consumers before implementation begins

About This Template

Created by: Tim Adair

Last Updated: 3/4/2026

Version: 1.0.0

License: Free for personal and commercial use

Frequently Asked Questions

When should I use URL path versioning versus header-based versioning?+
URL path versioning (`/v1/resource`) is simpler for consumers to understand and easier to test in a browser or curl. Header-based versioning (`Accept: application/vnd.api+json; version=2`) is cleaner in URL design but harder to debug. For most product APIs with fewer than 1,000 consumers, URL path versioning is the practical choice. The [API-First Design glossary entry](/glossary/api-first-design) covers how versioning fits into the broader API design philosophy.
How do I decide between REST and GraphQL for a new API?+
Use REST when your consumers need simple CRUD operations on well-defined resources, when caching matters (REST leverages HTTP caching natively), or when most consumers are external partners. Use [GraphQL](/glossary/graphql) when consumers need flexible queries across deeply nested relationships, when mobile bandwidth is a constraint (clients fetch exactly what they need), or when your internal frontend team is the primary consumer.
How detailed should error responses be?+
Detailed enough for the consumer to fix the problem without contacting support. Include a machine-readable code (for programmatic handling), a human-readable message (for debugging), field-level details (for form validation), and a documentation URL. Never expose internal stack traces or database errors in production responses.
Should list endpoints return total count?+
Include `total_count` only if your database can compute it efficiently. For large tables, `COUNT(*)` can be expensive. If you include it, document that the count may be approximate for large datasets. Always include `has_more` so consumers know whether to paginate, regardless of whether you include a total count.
How do I handle authentication for server-to-server versus user-facing API calls?+
Use API keys for server-to-server integrations where a specific user context is not needed. Use OAuth 2.0 with user tokens when the API call needs to act on behalf of a specific user. Document both flows clearly and ensure [rate limits](/glossary/rate-limiting) differ by auth type, since server-to-server integrations typically need higher throughput. ---

Explore More Templates

Browse our full library of AI-enhanced product management templates

Free PDF

Like This Template?

Subscribe to get new templates, frameworks, and PM strategies delivered to your inbox.

or use email

Instant PDF download. One email per week after that.

Want full SaaS idea playbooks with market research?

Explore Ideas Pro →