Agent Skills: Navan Install & Auth

|

UncategorizedID: jeremylongshore/claude-code-plugins-plus-skills/navan-install-auth

Install this agent skill to your local

pnpm dlx add-skill https://github.com/jeremylongshore/claude-code-plugins-plus-skills/tree/HEAD/plugins/saas-packs/navan-pack/skills/navan-install-auth

Skill Files

Browse the full folder contents for navan-install-auth.

Download Skill

Loading file tree…

plugins/saas-packs/navan-pack/skills/navan-install-auth/SKILL.md

Skill Metadata

Name
navan-install-auth
Description
|

Navan Install & Auth

Overview

Configure OAuth 2.0 client credentials for the Navan REST API. Navan has no public SDK — all API access uses raw REST calls with bearer tokens obtained via the client_credentials grant.

Purpose: Obtain a working OAuth 2.0 bearer token for calling Navan API endpoints.

Prerequisites

  • Navan admin access — you need the Admin or Travel Admin role
  • Node.js 18+ (for TypeScript) or Python 3.8+ (for Python)
  • A .env-aware project (dotenv for Node, python-dotenv for Python)
  • Navan Business tier or higher (free for up to 300 employees)

Instructions

Step 1: Create OAuth Credentials in Navan Dashboard

Navigate to: Admin > Travel admin > Settings > Integrations > Navan API Credentials > Create New

Save the client_id and client_secret immediately — credentials are only viewable once. If lost, you must revoke and regenerate.

Step 2: Store Credentials Securely

Create a .env file in your project root:

# .env — NEVER commit this file
NAVAN_CLIENT_ID="your-client-id-here"
NAVAN_CLIENT_SECRET="your-client-secret-here"
NAVAN_BASE_URL="https://api.navan.com"

Ensure .env is in your .gitignore:

echo ".env" >> .gitignore

Step 3: Token Exchange (TypeScript)

Install dependencies and implement the OAuth 2.0 client credentials flow:

npm install dotenv
import 'dotenv/config';

interface TokenResponse {
  access_token: string;
  token_type: string;
  expires_in: number;
}

async function getNavanToken(): Promise<string> {
  const response = await fetch(`${process.env.NAVAN_BASE_URL}/ta-auth/oauth/token`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    body: new URLSearchParams({
      grant_type: 'client_credentials',
      client_id: process.env.NAVAN_CLIENT_ID!,
      client_secret: process.env.NAVAN_CLIENT_SECRET!,
    }),
  });

  if (!response.ok) {
    const error = await response.text();
    throw new Error(`Auth failed (${response.status}): ${error}`);
  }

  const data: TokenResponse = await response.json();
  return data.access_token;
}

// Verify connection
const token = await getNavanToken();
console.log('Auth successful — token acquired');

Step 4: Token Exchange (Python)

pip install requests python-dotenv
import os
import requests
from dotenv import load_dotenv

load_dotenv()

def get_navan_token() -> str:
    """Exchange client credentials for an OAuth 2.0 bearer token."""
    response = requests.post(
        f"{os.environ['NAVAN_BASE_URL']}/ta-auth/oauth/token",
        data={
            "grant_type": "client_credentials",
            "client_id": os.environ["NAVAN_CLIENT_ID"],
            "client_secret": os.environ["NAVAN_CLIENT_SECRET"],
        },
    )
    response.raise_for_status()
    return response.json()["access_token"]

token = get_navan_token()
print("Auth successful — token acquired")

Step 5: Verify Connection

Make an authenticated API call to confirm credentials work:

const bookings = await fetch(`${process.env.NAVAN_BASE_URL}/v1/bookings?page=0&size=50`, {
  headers: { Authorization: `Bearer ${token}` },
});

if (bookings.ok) {
  const { data } = await bookings.json();
  console.log(`Connection verified — retrieved ${data.length} bookings`);
} else {
  console.error(`Verification failed: ${bookings.status}`);
}

Output

Successful completion produces:

  • OAuth 2.0 client_id and client_secret stored in .env
  • A getNavanToken() function (TypeScript or Python) returning a bearer token
  • A verified connection to the Navan API confirmed by a successful GET request

Error Handling

| Error | Code | Cause | Solution | |-------|------|-------|----------| | Invalid credentials | 401 | Wrong client_id or client_secret | Regenerate credentials in Admin > Integrations | | Insufficient permissions | 403 | Account lacks API access or wrong tier | Contact Navan support to enable API access | | Rate limited | 429 | Too many auth requests | Implement token caching (see navan-local-dev-loop) | | Endpoint not found | 404 | Wrong base URL or path | Verify NAVAN_BASE_URL is https://api.navan.com | | Server error | 500 | Navan service issue | Retry after 30 seconds; check Navan status page | | Service unavailable | 503 | Navan maintenance window | Wait and retry; check for scheduled maintenance |

Examples

Minimal auth check script:

# Quick credential test with curl
curl -s -X POST https://api.navan.com/ta-auth/oauth/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials&client_id=$NAVAN_CLIENT_ID&client_secret=$NAVAN_CLIENT_SECRET" \
  | python3 -c "import sys,json; d=json.load(sys.stdin); print('OK' if 'access_token' in d else 'FAIL')"

Resources

Next Steps

After authentication is working, proceed to navan-hello-world to make your first API call, or see navan-sdk-patterns to build a reusable typed wrapper.