How to Pass Null Value in REST API POST, PUT, and PATCH

How to pass null value in REST API using the JSON null literal in POST, PUT, and PATCH. Includes examples for query parameters and OpenAPI specs.

Jump to section

Jump to section

Jump to section

Handling null values correctly in REST APIs is fundamental to building reliable integrations, yet many developers struggle with the nuances between null, empty strings, and omitted fields. These distinctions matter because servers, databases, and client SDKs interpret each case differently, and getting it wrong can lead to data corruption or unexpected behavior.

This guide covers how to pass null values in JSON payloads, handle them across different HTTP contexts like query parameters and headers, and define nullable fields properly in OpenAPI specifications. You'll learn the practical differences between null semantics across programming languages, best practices for API design, and how tools like Stainless SDK generation can provide compile-time safety for nullable types.

Null, empty, and missing values compared

To pass a null value in a REST API, you should use the JSON literal null in the request body for methods like POST, PUT, or PATCH. This explicitly tells the server that a value is absent. It is fundamentally different from an empty string (""), which represents a present but empty text value, or an omitted field, which implies the client is not providing any information about that field.

Understanding the distinction is crucial because servers, databases, and client SDKs treat these cases differently.

  • null value: The field is present, but its value is explicitly null. This often means "no value" or "unknown."
    { "description": null }

  • Empty string: The field is present, and its value is a string of zero length. This is a valid string, not an absence of a value.
    { "description": "" }

  • Omitted field: The field is not included in the JSON object at all. This is useful for optional fields or in PATCH requests where you only send fields you want to change.
    {}

A server might interpret an omitted description as "do not change the description," while description: null could mean "clear the description." This distinction gives you precise control over your API interactions.

Null value semantics in REST APIs

The null you see in a JSON payload is a formal data type within the JSON specification, just like string, number, or boolean. When your application serializes data to send to an API, your language's concept of null is converted into this JSON null type.

This means Python's None, Go's nil, and Java's null all become the same thing over the wire.

A common point of confusion, especially for frontend developers, is the difference between null and undefined in JavaScript. While both can represent the absence of a value, JSON.stringify() treats them differently. A key with a null value is preserved, while a key with an undefined value is omitted from the resulting JSON string entirely.

Warning: Be careful not to send the string "null". This is a four-character string, not the JSON null type, and will almost certainly cause validation errors or unexpected behavior on the server.

Pass null values in JSON payloads

Sending null is most common in the body of POST, PUT, and PATCH requests. Here’s how you can do it in practice and how different languages handle the serialization.

Body payload examples

Using curl, you can send a JSON payload with a null value directly. This example sends a request to update a user's middle name to null.

curl -X PATCH https://api.example.com/v1/users/123 \
  -H "Content-Type: application/json" \
  -d '{
    "middle_name": null
  }'

With a strongly-typed SDK, like one generated by the Stainless SDK generator, this becomes even simpler and safer. The SDK handles the JSON serialization for you, and the type system ensures you can't make a mistake.

// Using a Stainless-generated TypeScript SDK
import { ExampleClient } from 'example-sdk';

const client = new ExampleClient({ apiKey: '...' });

await client.users.update('123', {
  middle_name: null,
});

Language serialization rules

Most standard libraries for handling JSON automatically convert the language's native null type into the JSON null literal.

  • JavaScript: JSON.stringify({ middle_name: null }) produces '{"middle_name":null}'.

  • Python: json.dumps({'middle_name': None}) produces '{"middle_name": null}'.

  • Java (with Jackson): Serializing an object where a field is set to null will correctly write it as null in the JSON output.

Multipart form data constraints

Passing a true null value in a multipart/form-data request is not natively supported. Multipart requests are designed to send a series of key-value pairs, where values are typically strings or file data.

Common workarounds include:

  • Omitting the field entirely if the server is designed to interpret its absence as a no-op.

  • Sending the field with an empty string value (middle_name=) and having the server logic interpret an empty string as null. This requires clear API documentation.

Handle null values across scenarios

While JSON bodies are the most common place to see null, the concept of "no value" appears in other parts of an API call. Here’s how it's handled in different contexts.

Query parameters and URLs

There is no official standard for representing null in a URL query string. The most common and recommended approach is to simply omit the parameter. If a user's status is null, you would make a request to /users instead of trying to represent null in /users?status=null.

Another pattern is to send the parameter with an empty value, like /users?status=. This requires the server to be explicitly coded to interpret an empty status parameter as a filter for null statuses.

Request headers limitations

HTTP headers are key-value strings. Similar to query parameters, you cannot send a "null" value. The contract for optional headers is based on their presence or absence. If you don't need to send an X-Customer-ID header, you just don't include it in the request.

HTTP method semantics

The meaning of null can be tied to the HTTP method being used.

  • GET: A response to a GET request can contain fields with null values, indicating that data for those fields does not exist.

  • PATCH: This is a primary use case for null. Sending { "middle_name": null } is a clear instruction to the server to clear the value of the middle_name field.

  • DELETE: A successful DELETE request often returns a 204 No Content response with an empty body, which is conceptually similar to null.

Arrays and nested objects

JSON null can be used anywhere a value is expected, including inside arrays and as the value for a nested object.

  • In an array: { "tag_ids": [101, null, 105] } could signify that the middle tag is unassigned.

  • As an object value: { "user": { "address": null } } clearly indicates the user has no address on file.

Specify null behaviour in OpenAPI specs

For API producers who create OpenAPI specs, clearly defining which fields can be null is essential for a good developer experience. The OpenAPI specification provides a standard way to do this, which tools like Stainless use to generate high-quality, type-safe SDKs.

Nullable flag in OpenAPI 3.0

In OpenAPI 3.0, you can indicate that a field can be null by adding nullable: true to its schema definition.

components:
  schemas:
    User:
      type: object
      properties:
        middle_name:
          type: string
          nullable: true # This field can be a string or null

Union syntax in OpenAPI 3.1

OpenAPI 3.1 aligns more closely with the JSON Schema standard and uses a type array to represent a union of types. This is the more modern and explicit way to define a nullable field.

components:
  schemas:
    User:
      type: object
      properties:
        middle_name:
          type: [string, "null"] # This field can be a string or null

Stainless SDK generation impact

When you define fields as nullable in your OpenAPI spec, code generation tools can create much safer and more ergonomic SDKs. For example, Stainless reads your spec and generates corresponding nullable types in each language.

  • TypeScript: A field defined as type: [string, "null"] becomes middle_name: string | null;. This provides compile-time safety, preventing developers from accidentally treating a potentially null value as if it were always a string, which eliminates a whole class of runtime errors. Remember that your API isn't finished until the SDK ships with this level of type safety built in.

  • Python: The same field becomes middle_name: Optional[str].

This provides compile-time safety, preventing developers from accidentally treating a potentially null value as if it were always a string, which eliminates a whole class of runtime errors.

Required versus optional fields

A field can be both required and nullable. This means the key must always be present in the JSON object, but its value is allowed to be null. This is different from an optional field, where the key itself can be omitted.

Apply best practices for null values

Handling null consistently and predictably is a hallmark of a well-designed API. Here are some best practices to follow.

  • Be explicit. Use null to explicitly clear a field's value. For optional data that isn't being provided, prefer omitting the field from the payload.

  • Avoid ambiguity. Never use an empty string ("") as a stand-in for null. An empty string is a valid value, whereas null signifies the absence of one.

  • Document everything. Your API reference should clearly state which fields are nullable and how the server interprets null values for each endpoint, especially for PATCH operations. You should also integrate SDK snippets with your API docs to help developers understand exactly how to handle these nullable fields in their code.

  • Test your null paths. Your automated tests should include cases for sending null values to ensure the server behaves as expected.

  • Leverage tooling. Use tools that can analyze your OpenAPI spec for inconsistencies. For instance, Stainless provides diagnostics that can flag issues with how nullable fields are defined and used, helping you maintain a robust API contract.

Frequently asked questions about null values in REST APIs

Here are answers to some common questions developers have about handling null in REST APIs.

How do I pass a null query parameter?

You can't pass a true null. The best practice is to omit the parameter entirely, but some APIs use a convention where an empty parameter (e.g., ?status=) is interpreted as a filter for null values.

How do I clear a field with JSON Patch?

You can use the "replace" operation with a null value. For a field named middle_name, the JSON Patch operation would be { "op": "replace", "path": "/middle_name", "value": null }.

How do I validate nullable fields in popular frameworks?

Most modern validation libraries have built-in support for nullable types. For example, in Python's Pydantic, you'd define a field as middle_name: Optional[str] = None.

How do Stainless SDKs represent nullable types?

Stainless generates idiomatic nullable types for each language, such as string | null in TypeScript, Optional[str] in Python, *string (a pointer to a string) in Go, and Optional<String> in Java.

Does using null break backward compatibility?

Adding a new nullable field to a response is generally a non-breaking change. However, changing an existing, non-nullable field to be nullable can be a breaking change for clients that are not prepared to handle null. Making Java nullable fields backwards compatible requires careful consideration of these constraints.