From navan-pack
Sets up OAuth 2.0 client credentials for Navan REST API: dashboard creation, .env storage, Node.js/TypeScript or Python token exchange code. Use for new integrations or credential rotation.
npx claudepluginhub jeremylongshore/claude-code-plugins-plus-skills --plugin navan-packThis skill is limited to using the following tools:
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.
Builds typed TypeScript NavanAPI client for REST endpoints with OAuth2 token refresh, retries, typed responses, and error handling. For production Navan travel SaaS integrations.
Guides OAuth client setup for API integrations with step-by-step instructions, production-ready code, configurations, and best practices. Auto-activates on 'oauth client setup' phrases.
Guides Next.js Cache Components and Partial Prerendering (PPR): 'use cache' directives, cacheLife(), cacheTag(), revalidateTag() for caching, invalidation, static/dynamic optimization. Auto-activates on cacheComponents: true.
Share bugs, ideas, or general feedback.
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.
.env-aware project (dotenv for Node, python-dotenv for Python)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.
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
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');
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")
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}`);
}
Successful completion produces:
client_id and client_secret stored in .envgetNavanToken() function (TypeScript or Python) returning a bearer token| 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 |
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')"
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.