Back to Nodes

Json Api Serializer

Last updated May 6, 2026

Set of tools to parse/format or serialize/deserialize data for JSON API Specification

32 Weekly Downloads
290 Monthly Downloads

Included Nodes

Json Api Serializer

Description

n8n-nodes-json-api-spec

This is an n8n community node. It lets you serialize data to JSON API Specification format in your n8n workflows.

JSON API is a specification for building APIs in JSON. This node helps you transform your data into JSON API compliant format with proper structure including resource type, id, and attributes.

n8n is a fair-code licensed workflow automation platform.

Installation
Operations
Compatibility
Usage
Resources
TODO

Installation

Follow the installation guide in the n8n community nodes documentation.

Operations

The JSON API Serializer node supports the following operations:

Serialize Resource Object

Serializes a single resource into JSON API format with a data object containing:

  • id – The resource identifier
  • type – The resource type
  • attributes – The resource attributes as a JSON object
  • Serialize Resources Array

    Serializes multiple resources into JSON API format with a data array, where each item contains:

  • id – The resource identifier
  • type – The resource type
  • attributes – The resource attributes as a JSON object
  • Serialize Resource Object and Array with Relationships

    Enable Include Relationships will add data.relationships and included keys with the resources provided.

    Each included resource supports two relationship types:

  • One to One (default) — emits a single resource identifier object: { "data": { "id": "1", "type": "sector" } }
  • One to Many — emits an array of resource identifiers: { "data": [{ "id": "1", "type": "role" }, { "id": "2", "type": "role" }] }
  • Include Filter

    When “Enable Include Relationships” is enabled, you can use the Include Filter field to control which relationships are returned in the response. This is useful for implementing the JSON API include query parameter pattern.

  • Include Filter: A comma-separated list of relationship names to include (e.g., sector,owner)
  • If empty, no relationships or included resources will be returned
  • The filter matches against the Relationship Name configured on each included resource
  • Default value pulls from $('Webhook').first().json.query.include to automatically use the include parameter from incoming API requests
  • Pagination Support (Array Only)

    When serializing an array of resources, you can enable pagination to add JSON API compliant links and meta sections:

  • links – Contains first, prev, next, last URLs for navigation
  • meta – Contains page info (current, size, total) and total resource count
  • Compatibility

  • Tested against: n8n 1.113.3
  • Usage

    Basic Example – Single Resource

    Input parameters:

  • Response: Resource Object
  • Type: organization
  • ID: 42
  • Attributes: {"name": "Agile Freaks SRL", "country": "Romania", "region": "Sibiu"}
  • Output:

    {
      "data": {
        "id": "42",
        "type": "organization",
        "attributes": {
          "name": "Agile Freaks SRL",
          "country": "Romania",
          "region": "Sibiu"
        }
      }
    }
    

    Multiple Resources Example

    Input parameters:

  • Response: Resources Array
  • Configure the Type, ID, and Attributes for each input item
  • Output:

    {
      "data": [
        {
          "id": "1",
          "type": "organization",
          "attributes": {
            "name": "Agile Freaks SRL",
            "country": "USA"
          }
        },
        {
          "id": "2",
          "type": "organization",
          "attributes": {
            "name": "Agile Freaks SRL",
            "country": "Germany"
          }
        }
      ]
    }
    

    Example with Relationships and Included Resources

    Input parameters:

  • Response: Resource Object
  • Type: organization
  • ID: 6937
  • Attributes: {"name": "Test organization", "country": "Kenya", "region": "africa"}
  • Enable Include Relationships: true
  • Include Filter: {{ $('Webhook').first().json.query.include }} (default)
  • Include Resources:
  • – Resource:
    – Type: sector
    – Relationship Name: sector
    – Relationship Type: One to One (default)
    – Attributes: {"id": "1", "name": "Technology"}

    Output:

    {
      "data": {
        "id": "6937",
        "type": "organization",
        "attributes": {
          "name": "Test organization",
          "country": "Kenya",
          "region": "africa"
        },
        "relationships": {
          "sector": {
            "data": {
              "id": "1",
              "type": "sector"
            }
          }
        }
      },
      "included": [
        {
          "id": "1",
          "type": "sector",
          "attributes": {
            "name": "Technology"
          }
        }
      ]
    }
    

    Example with Include Filter

    This example shows how to filter which relationships are returned. When you have multiple relationships configured but only want to return specific ones based on the API request.

    Input parameters:

  • Response: Resource Object
  • Type: organization
  • ID: 42
  • Attributes: {"name": "Agile Freaks SRL", "country": "Romania"}
  • Enable Include Relationships: true
  • Include Filter: sector (only return sector, not owner)
  • Include Resources:
  • – Resource:
    – Type: sector
    – Relationship Name: sector
    – Relationship Type: One to One (default)
    – Attributes: {"id": "1", "name": "Technology"}
    – Resource:
    – Type: owner
    – Relationship Name: owner
    – Relationship Type: One to One (default)
    – Attributes: {"id": "1", "name": "Boss"}

    Output:

    {
      "data": {
        "id": "42",
        "type": "organization",
        "attributes": {
          "name": "Agile Freaks SRL",
          "country": "Romania"
        },
        "relationships": {
          "sector": {
            "data": {
              "id": "1",
              "type": "sector"
            }
          }
        }
      },
      "included": [
        {
          "id": "1",
          "type": "sector",
          "attributes": {
            "name": "Technology"
          }
        }
      ]
    }
    

    Note that even though both sector and owner are configured as Include Resources, only sector appears in the output because the Include Filter is set to sector. This allows you to configure all possible relationships once and dynamically filter them based on the incoming API request’s include parameter.

    Example with Multiple Included Resources

    Input parameters:

  • Response: Resource Object
  • Type: organization
  • ID: 42
  • Attributes: {"name": "Agile Freaks SRL", "country": "Romania", "region": "Sibiu"}
  • Enable Include Relationships: true
  • Include Filter: {{ $('Webhook').first().json.query.include }} (default)
  • Include Resources:
  • – Resource:
    – Type: sector
    – Relationship Name: sector
    – Relationship Type: One to One (default)
    – Attributes: {"id": "1", "name": "Technology"}
    – Resource:
    – Type: owner
    – Relationship Name: owner
    – Relationship Type: One to One (default)
    – Attributes: {"id": "1", "name": "Boss"}

    Output:

    {
      "data": {
        "id": "42",
        "type": "organization",
        "attributes": {
          "name": "Agile Freaks SRL",
          "country": "Romania",
          "region": "Sibiu"
        },
        "relationships": {
          "sector": {
            "data": {
              "id": "1",
              "type": "sector"
            }
          },
          "owner": {
            "data": {
              "id": "1",
              "type": "owner"
            }
          }
        }
      },
      "included": [
        {
          "id": "1",
          "type": "sector",
          "attributes": {
            "name": "Technology"
          }
        },
        {
          "id": "1",
          "type": "owner",
          "attributes": {
            "name": "Boss"
          }
        }
      ]
    }
    

    Example with Custom Relationship Name

    You can specify a custom name for relationships that differs from the resource type. This is useful when the semantic meaning of the relationship differs from the resource type itself.

    Input parameters:

  • Response: Resource Object
  • Type: contact
  • ID: 42
  • Attributes: {"name": "Mister Daniel"}
  • Enable Include Relationships: true
  • Include Filter: {{ $('Webhook').first().json.query.include }} (default)
  • Include Resources:
  • – Resource:
    – Type: organization
    – Relationship Name: membership
    – Relationship Type: One to One (default)
    – Attributes: {"id": "42", "name": "Agile Freaks SRL", "country": "Romania", "region": "Sibiu"}

    Output:

    {
      "data": {
        "id": "42",
        "type": "contact",
        "attributes": {
          "name": "Mister Daniel"
        },
        "relationships": {
          "membership": {
            "data": {
              "id": "42",
              "type": "organization"
            }
          }
        }
      },
      "included": [
        {
          "id": "42",
          "type": "organization",
          "attributes": {
            "name": "Agile Freaks SRL",
            "country": "Romania",
            "region": "Sibiu"
          }
        }
      ]
    }
    

    In this example, even though the resource type is organization, the relationship is named membership to better represent the semantic relationship between a contact and their organization.

    Example with One-to-Many Relationships

    Use Relationship Type: One to Many when a resource has multiple related items of the same type (e.g., a contact with multiple roles). Instead of configuring a single attributes object, provide a Source Array expression that resolves to an array of objects and an optional Attribute Keys list.

    Input parameters:

  • Response: Resource Object
  • Type: contact
  • ID: 42
  • Attributes: {"name": "Mister Daniel"}
  • Enable Include Relationships: true
  • Include Filter: roles
  • Include Resources:
  • – Resource:
    – Type: role
    – Relationship Name: roles
    – Relationship Type: One to Many
    – Source Array: ={{ $json.roles }} (resolves to [{"id": "10", "name": "CEO"}, {"id": "11", "name": "Contact Point"}])
    – Attribute Keys: id,name

    Output:

    {
      "data": {
        "id": "42",
        "type": "contact",
        "attributes": {
          "name": "Mister Daniel"
        },
        "relationships": {
          "roles": {
            "data": [
              { "id": "10", "type": "role" },
              { "id": "11", "type": "role" }
            ]
          }
        }
      },
      "included": [
        {
          "id": "10",
          "type": "role",
          "attributes": {
            "name": "CEO"
          }
        },
        {
          "id": "11",
          "type": "role",
          "attributes": {
            "name": "Contact Point"
          }
        }
      ]
    }
    

    One-to-Many Notes:

  • Source Array accepts an n8n expression that resolves to a JSON array at runtime — ideal for dynamic data from upstream nodes
  • Attribute Keys is a comma-separated list of fields to extract from each array item (e.g. id,name). Leave empty to include all fields
  • The id field is always extracted from each item and used as the resource identifier — it will not appear in attributes
  • Each item in the source array becomes a separate entry in both relationships.data and included
  • Example with Pagination

    Input parameters:

  • Response: Resources Array
  • Type: contact
  • Add Pagination: enabled
  • Base URL: http://localhost:5678/webhook/v1/contacts
  • Current Page: 2
  • Items Per Page: 200
  • Total Resource Count: 800
  • Query Params: {"filter": {"organization_id": "42"}, "sort": "name"}
  • Output:

    {
      "data": [
        {
          "id": "1",
          "type": "contact",
          "attributes": {
            "name": "John Doe"
          }
        },
        {
          "id": "2",
          "type": "contact",
          "attributes": {
            "name": "Jane Smith"
          }
        }
      ],
      "links": {
        "first": "http://localhost:5678/webhook/v1/contacts?filter%5Borganizationid%5D=42&sort=name&page=1&perpage=200",
        "prev": "http://localhost:5678/webhook/v1/contacts?filter%5Borganizationid%5D=42&sort=name&page=1&perpage=200",
        "next": "http://localhost:5678/webhook/v1/contacts?filter%5Borganizationid%5D=42&sort=name&page=3&perpage=200",
        "last": "http://localhost:5678/webhook/v1/contacts?filter%5Borganizationid%5D=42&sort=name&page=4&perpage=200"
      },
      "meta": {
        "page": {
          "current": 2,
          "size": 200,
          "total": 4
        },
        "totalcontactcount": 800
      }
    }
    

    Pagination Notes:

  • prev is null on the first page
  • next is null on the last page
  • The totalcount key is dynamically named based on the resource type
  • Query Params accepts a JSON object (e.g., from $('Webhook').first().json.query) and preserves all params except page and per_page
  • Nested objects like filter[organization_id] are properly serialized
  • Tips

  • The Attributes field accepts JSON format – make sure your JSON is valid
  • The Include Resources field is optional. Add one or more resources that will appear in both the relationships and included sections
  • – Each included resource requires a Type, a Relationship Name, and a Relationship Type
    Relationship Type controls the output format:
    One to One (default): provide Attributes as a JSON object including an id field. Outputs { "data": { "id": "…", "type": "…" } }
    One to Many: provide a Source Array expression and an optional Attribute Keys list. Outputs { "data": [ … ] } — always an array, even when empty
    – The id field is always extracted from each resource and used as the relationship identifier — it will not appear in attributes
    – Empty to-many relationships (data: []) are valid per the JSON API spec and will be included in the output

  • Use the Resource Object response type when you need to serialize a single item
  • Use the Resources Array response type when working with multiple items from previous nodes
  • The node follows the JSON API v1.0 specification
  • Resources

  • n8n community nodes documentation
  • JSON API Specification
  • JSON API Format Documentation
  • Development Setup

    1. Clone this repository.
    2. Install node and npm. https://nodejs.org/en/download
    3. Install pnpm

    npm i -g pnpm
    

    4. Install local package

    pnpm install
    

    5. Build n8n

    pnpm run build
    

    6. Run n8n in docker mode
    7. Configure n8n docker container to use this custom node. Add the following volume for n8n-main service. You have to determine YOUR_PATH by running pwd in the location you cloned this repo at. Can look something like /Users/.../n8n-nodes-json-api-spec.

      volumes:
        - {YOURPATH}/dist:/home/node/.n8n/custom/nodemodules/n8n-nodes-json-api-spec
    

    Development

    1. Make changes to nodes or credentials
    2. Delete compiled files

    rm -rf dist
    

    3. Build packages and n8n

    pnpm run build
    

    4. Restart n8n (make sure to be in n8n directory)

    docker compose restart n8n-main
    

    Publishing Package on npm

    1. Update version (patch / minor / major)

    npm version patch
    

    2. Push version update on git

    git push
    

    3. Publish version on npm

    npm publish
    

    TODO

  • [ ] Add Error Json Api Serializer node

License

MIT