Skip to content
Developer Template5 columns · 5 sample rows· Updated

REST & GraphQL API Parameters Markdown Table Template

A parameter table is the part of an API reference that people read while they are composing a request. For each input it answers four things: what it is called on the wire, what type the server expects, whether the request fails without it, and what the server does when it is left out. Without that table, integrators copy an old curl example and learn the limits from a stream of 400 responses.

Edit This Template

Edit cells, add rows, or sort — the Markdown updates live
Row
1
page
1
2
limit
50
3
sort_by
Field to sort results by (created_at, name)
created_at
4
filter
null
5
Authorization (header)
Bearer token sent as Authorization: Bearer <token>
Output
| Parameter                |  Type   | Required | Description                                          |      Default |
| :----------------------- | :-----: | :------: | :--------------------------------------------------- | -----------: |
| `page`                   | integer |    No    | Page offset for paginated record retrieval           |          `1` |
| `limit`                  | integer |    No    | Maximum records returned per response (max: 100)     |         `50` |
| `sort_by`                | string  |    No    | Field to sort results by (`created_at`, `name`)      | `created_at` |
| `filter`                 | string  |    No    | Filter expression for search narrowing               |       `null` |
| `Authorization` (header) | string  |   Yes    | Bearer token sent as `Authorization: Bearer <token>` |            — |
5 rows × 5 columns
Rendered Preview
ParameterTypeRequiredDescriptionDefault
pageintegerNoPage offset for paginated record retrieval1
limitintegerNoMaximum records returned per response (max: 100)50
sort_bystringNoField to sort results by (created_at, name)created_at
filterstringNoFilter expression for search narrowingnull
Authorization (header)stringYesBearer token sent as Authorization: Bearer <token>—

When to Use This Table

The readers are concrete. An SDK author needs exact names and types to generate a typed client. A frontend developer building a list view needs to know how pagination and sorting behave by default. A QA engineer needs the bounds — the largest limit, the legal sort_by values — to write edge-case tests. The Default column carries the most behavioural weight: an omitted limit that returns 50 rows and one that returns 10,000 lead to very different performance in production.

A good parameter table states where each input travels (path, query string, header, or body), lists bounds and allowed values in the description, and agrees with the OpenAPI document or GraphQL schema the server actually validates against. A weak one lists names with descriptions like “the page” and nothing else. The template’s Authorization row shows the right habit: a credential is not a query parameter, so name the header it travels in, or move headers into their own table.

What Goes in Each Column

ColumnAlignmentWhat to put here
Parameterleft :---The exact name as sent, in backticks, with the server’s casing (sort_by and sortBy are different parameters). For nested body fields use dot notation such as user.profile.id, and items[].sku for fields inside arrays. Left-aligned so readers can scan the first characters down the column.
Typecenter :---:Use JSON Schema / OpenAPI vocabulary — string, integer, number, boolean, array, object — and add the format when it changes what is valid, such as string (uuid) or string (date-time). For GraphQL, write the schema type including nullability, like Int! or [String!]. Centered because the values are short tokens.
Requiredcenter :---:A centered Yes or No. Yes means the server rejects the request when the input is absent. A parameter with a server-side default is No. If it is required only in some cases, write Conditional and spell out the condition in Description rather than leaving readers to discover it.
Descriptionleft :---What the input changes, followed by its constraints: minimum and maximum, allowed values, format, and interactions with other parameters. Also say what happens out of range — whether the server clamps limit=500 down to 100 or returns a validation error. Those two behaviours need different client code.
Defaultright ---:The value the server applies when the input is omitted, in backticks and right-aligned so numbers line up. Use — for required inputs, which have no default. Avoid quoting query-string defaults ("created_at") because the quotes look like part of the value, and keep “no default, field absent” distinct from an explicit null.

How to Fill It In

  1. 1Start from whatever the server validates against: the parameters and requestBody sections of the OpenAPI document, the GraphQL SDL, or the request model in code (a Zod schema, Pydantic model, or Joi validator). Copy names character for character.
  2. 2For each input, record where it travels and its type, then read the validator for minimum, maximum, enum, and pattern rules. Those constraints belong in Description.
  3. 3Confirm defaults by experiment rather than memory: call the endpoint without the parameter and inspect the result, for example piping the response through jq to count the items returned.
  4. 4Probe the edges once — limit=0, limit=101, an unknown sort field — and note whether each one is clamped, ignored, or rejected.
  5. 5Format the table: backticks around names and default values, and \| for any literal pipe, including pipes inside backticks, because GFM splits cells on them before it reads code spans (see escaping pipes). The Markdown table formatter will realign the columns afterwards.
  6. 6Have the endpoint owner review it, and update the table in the same pull request that adds or changes a parameter so docs and server ship together.

Ready-to-Paste Variations

With a location column (path, query, header, body)

Mirrors the OpenAPI in field. Use it for endpoints that mix inputs from several places, such as this hypothetical POST /orgs/{orgId}/projects.

| Parameter | In | Type | Required | Description |
| :--- | :---: | :---: | :---: | :--- |
| `orgId` | path | string (uuid) | Yes | Organization that will own the project |
| `Authorization` | header | string | Yes | `Bearer <token>` with the `projects:write` scope |
| `Idempotency-Key` | header | string | No | Client-generated UUID; a retry with the same key returns the first response |
| `name` | body | string | Yes | 1–80 characters, unique within the organization |
| `visibility` | body | string | No | `private` or `internal`; defaults to `private` |

GraphQL field arguments

GraphQL expresses “required” through the ! in the type, so the Required column disappears and the type carries that information instead.

| Argument | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `first` | `Int` | `20` | Number of edges to return; maximum `100` |
| `after` | `String` | `null` | Cursor taken from `pageInfo.endCursor` of the previous page |
| `orderBy` | `ProjectOrder` | `{field: CREATED_AT, direction: DESC}` | Sort field and direction |
| `orgId` | `ID!` | — | Required; the organization to list projects for |

Nested request body fields

For JSON bodies with nested objects and arrays. Dot and [] notation keeps one row per leaf field without needing indentation.

| Field | Type | Required | Constraints |
| :--- | :---: | :---: | :--- |
| `customer.email` | string | Yes | Valid email address, at most 254 characters |
| `customer.locale` | string | No | BCP 47 language tag such as `en-GB` |
| `items[].sku` | string | Yes | Must exist in the product catalog |
| `items[].quantity` | integer | Yes | 1–999 |
| `payment.method` | string | Yes | `card` \| `invoice` |

Common Mistakes

  • Documenting credentials as query parameters, such as an api_key in the query string.

    Send keys in the Authorization header. Query strings end up in access logs, proxy logs, and browser history. Add an In column or a separate headers table so the location is explicit.

  • Marking an input optional without saying what omitting it does.

    Fill in Default, or describe the absent case in Description (“omit to return both active and archived projects”). “Optional” alone leaves the reader guessing.

  • Writing union values as asc|desc in a cell.

    The pipe ends the cell even inside backticks. Escape it as \|, or list the allowed values separated by commas.

  • Typing every identifier and date as plain string.

    Add the format: string (uuid), string (date-time), string (email). It tells client authors which parser and validator to use.

  • Copying defaults from an old README.

    Defaults change quietly during refactors. Verify each one against the running server before publishing, and again whenever the validator changes.

Browse all 50 templates
FAQ

REST & GraphQL API Parameters: Frequently Asked Questions

Should path, query, header, and body parameters go in one table?

For small endpoints, one table with an In column works well. When the body has nested objects, give the body its own table. That mirrors OpenAPI, which keeps parameters (path, query, header, cookie) separate from requestBody.

How do I document parameters for a GraphQL query?

Document the arguments of each field. A trailing ! in the type means the argument is non-null and therefore required. Defaults declared in the SDL are visible through introspection, so copy them from the schema. Give each input object type its own table.

Can I generate this table from an OpenAPI file?

Yes. Extract an endpoint’s parameters array as JSON with a tool such as jq, then paste it into the JSON to Markdown converter. Add descriptions and constraints by hand afterwards, because they rarely survive automated conversion intact.

What is the difference between a null default and no default?

A null default means the server treats omission as an explicit null, which may clear a value on update. No default (—) means the parameter is required, or simply absent from processing. On PATCH endpoints the difference decides whether a field is cleared or left alone.

How should I mark a deprecated parameter?

Keep the row, wrap the name in ~~strikethrough~~, and start the description with “Deprecated: use new_name instead”, plus the version or date it will be removed. In OpenAPI, also set deprecated: true so generated SDKs warn callers.