↑ ↓ to navigate
↵ to select
esc to close
GET Navigation

Navigation API

https://api.airogelcms.com/v1/accounts/:account_id/navigations

A navigation is a named menu, such as a main menu or a footer menu. It holds a tree of items. Each item is either a plain link (url) or a link to an entry, which follows the entry's URL when that changes. Items nest through parent_id.

Navigation operations

  • GET /v1/accounts/:account_id/navigations - List navigations
  • GET /v1/accounts/:account_id/navigations/:id - Get one navigation with its item tree
  • POST /v1/accounts/:account_id/navigations - Create a navigation
  • PUT / PATCH /v1/accounts/:account_id/navigations/:id - Update a navigation
  • DELETE /v1/accounts/:account_id/navigations/:id - Delete a navigation (returns 204)

:id is the navigation's nav_ ID or handle.

Item operations

  • GET /v1/accounts/:account_id/navigations/:navigation_id/items - List items (top-level items with nested children)
  • GET /v1/accounts/:account_id/navigations/:navigation_id/items/:id - Get one item
  • POST /v1/accounts/:account_id/navigations/:navigation_id/items - Create an item
  • PUT / PATCH /v1/accounts/:account_id/navigations/:navigation_id/items/:id - Update an item
  • DELETE /v1/accounts/:account_id/navigations/:navigation_id/items/:id - Delete an item (returns 204)

:navigation_id is the navigation's ID or handle. An item's :id must be its ni_ prefix ID, because items have no handle.

Navigation fields

FieldTypeRequiredDescription
titlestringyesDisplay name
handlestringyesIdentifier used in Liquid. POST with an existing handle updates that navigation.

Item fields

FieldTypeRequiredDescription
titlestringyesLink text
urlstringnoExplicit URL or path, for links that do not point to an entry
collection_handlestringnoWith entry_handle: link to that entry
entry_handlestringnoWith collection_handle: the entry to link to
priorityintegernoSort order among siblings, ascending. If you leave it out, the item goes after its existing siblings.
parent_idstringnoni_ ID of the parent item. It must be in the same navigation.

Parameters

Name Type Required Description
account_id string Required Path. Your account prefix ID (acct_...).
id string Optional Path. Navigation nav_ ID or handle (navigation endpoints). On item endpoints, the item's ni_ ID.
navigation_id string Optional Path, item endpoints. Navigation nav_ ID or handle.
handle string Optional Query, list only. Return only the record with exactly this handle.
all string Optional Query, item list only. true returns every item in a flat list (still paginated). By default only top-level items are listed, each with nested children.
page integer Optional Query, list only. Page number, starting at 1. The page size is fixed at 20.
title string Required Body. Navigation name, or item link text.
handle string Required Body, navigations only. Identifier. POST with an existing handle updates it.
url string Optional Body, items. Explicit link URL.
collection_handle string Optional Body, items. Collection of the linked entry.
entry_handle string Optional Body, items. Handle of the linked entry.
priority integer Optional Body, items. Sort order among siblings. Defaults to after the last sibling.
parent_id string Optional Body, items. ni_ ID of the parent item.

Request Example

# Create a navigation
curl -X POST "https://api.airogelcms.com/v1/accounts/$ACCOUNT_ID/navigations" \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"title": "Main Menu", "handle": "main_menu"}'

# Add a plain link
curl -X POST "https://api.airogelcms.com/v1/accounts/$ACCOUNT_ID/navigations/main_menu/items" \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"title": "Home", "url": "/", "priority": 1}'

# Add a link to an entry
curl -X POST "https://api.airogelcms.com/v1/accounts/$ACCOUNT_ID/navigations/main_menu/items" \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"title": "About Us", "priority": 2, "collection_handle": "pages", "entry_handle": "about"}'

# Nest an item under another one
curl -X POST "https://api.airogelcms.com/v1/accounts/$ACCOUNT_ID/navigations/main_menu/items" \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"title": "Our Team", "url": "/about/team", "parent_id": "ni_Hk2m8Pq"}'

# Get the navigation with its item tree
curl "https://api.airogelcms.com/v1/accounts/$ACCOUNT_ID/navigations/main_menu" \
  -H "Authorization: Bearer $API_TOKEN"

# List every item flat
curl "https://api.airogelcms.com/v1/accounts/$ACCOUNT_ID/navigations/main_menu/items?all=true" \
  -H "Authorization: Bearer $API_TOKEN"

# Move an item
curl -X PATCH "https://api.airogelcms.com/v1/accounts/$ACCOUNT_ID/navigations/main_menu/items/ni_Rt5v1Wz" \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"priority": 5}'

Response Example

// GET /navigations/main_menu - items here show only id, title, url, priority, timestamps and children
{
  "id": "nav_6pWq3Lm",
  "handle": "main_menu",
  "title": "Main Menu",
  "items_count": 3,
  "created_at": "2026-09-10T12:00:00Z",
  "updated_at": "2026-09-10T12:05:00Z",
  "items": [
    {
      "id": "ni_Rt5v1Wz",
      "title": "Home",
      "url": "/",
      "priority": 1,
      "created_at": "2026-09-10T12:01:00Z",
      "updated_at": "2026-09-10T12:01:00Z"
    },
    {
      "id": "ni_Hk2m8Pq",
      "title": "About Us",
      "url": null,
      "priority": 2,
      "created_at": "2026-09-10T12:02:00Z",
      "updated_at": "2026-09-10T12:02:00Z",
      "children": [
        { "id": "ni_Zb7c4Xn", "title": "Our Team", "url": "/about/team", "priority": 1,
          "created_at": "2026-09-10T12:03:00Z", "updated_at": "2026-09-10T12:03:00Z" }
      ]
    }
  ]
}

// POST/PUT /navigations and GET /navigations (list items) return the navigation without "items"

// Item endpoints (GET/POST/PUT .../items/:id) add parent_id and, for linked items, entity
{
  "id": "ni_Hk2m8Pq",
  "title": "About Us",
  "url": null,
  "priority": 2,
  "created_at": "2026-09-10T12:02:00Z",
  "updated_at": "2026-09-10T12:02:00Z",
  "parent_id": null,
  "entity": {
    "type": "CollectionEntry",
    "id": "cnety_3sDf9Gh",
    "handle": "about",
    "title": "About",
    "url": "/about"
  },
  "children": [
    { "id": "ni_Zb7c4Xn", "title": "Our Team", "url": "/about/team", "priority": 1,
      "created_at": "2026-09-10T12:03:00Z", "updated_at": "2026-09-10T12:03:00Z", "parent_id": "ni_Hk2m8Pq" }
  ]
}

// GET .../items
{
  "data": [ { "id": "ni_Rt5v1Wz", "title": "Home", "url": "/", "priority": 1, "parent_id": null, "...": "..." } ],
  "pagination": {
    "page": 1,
    "per_page": 20,
    "total": 1,
    "total_pages": 1,
    "next_page": null,
    "prev_page": null
  }
}

Additional Notes

Two item shapes. GET /navigations/:id embeds the item tree, but those items carry only id, title, url, priority, timestamps and children. The /items endpoints also return parent_id and, for items linked to an entry, an entity object. children is present only when an item has children. Create and update on a navigation return it without items.

Linked items. For items linked with collection_handle + entry_handle, url is null and the page URL is entity.url. That URL follows the entry if its path changes, and it is what templates render.

Create is idempotent. POSTing an item with the same title and url (or the same title and linked entry) as an existing item in the navigation updates that item instead of adding a duplicate.

Unresolved references. On update, an unknown collection_handle/entry_handle pair or parent_id returns 422 (path: "entry_handle" or "parent_id"). On create, they are currently ignored, and the item is created without the link or parent. Check the response.

Sorting. Items are ordered by priority ascending within their parent.

Deleting a navigation deletes all of its items. See Liquid Templates for rendering menus.