Skip to main content

Public API Access Guide

This guide explains how to access the Enterprise AI Public API using OAuth 2.0 Client Credentials Flow. The Vertical Template provides a server-side proxy pattern that keeps credentials secure while enabling API access.

Overview

The Public API at https://test-api.myenterprise.ai/ provides enterprise AI capabilities. Access is controlled through Microsoft Entra ID (Azure AD) using the Client Credentials Flow.

What is Client Credentials Flow?

Client Credentials Flow is an OAuth 2.0 grant type for server-to-server authentication:

  • No user context required - Uses application identity, not user identity
  • Server-side only - Credentials never exposed to browser
  • Automatic token management - Tokens cached and refreshed automatically

Architecture

                          PUBLIC API PROXY ARCHITECTURE

+-----------+ +----------------------+ +-------------------+
| Browser | | Next.js API Route | | Entra ID |
| (Client) | | (Server-Side Proxy) | | Token Endpoint |
+-----+-----+ +----------+-----------+ +---------+---------+
| | |
| POST /api/eai/ | |
| public/v3/endpoint | |
| ------------------> | |
| | |
| | POST /oauth2/v2.0/token |
| | grant_type=client_creds |
| | ------------------------>|
| | |
| | { access_token: "..." } |
| | <------------------------|
| | |
| v |
| +---------------+ |
| | Public API | |
| | test-api. | |
| | myenterprise | |
| +---------------+ |
| | |
| { data: ... } | |
| <------------------- | |

Key Points:

  • Tokens are acquired server-side using client credentials
  • Client (browser) never sees credentials or raw tokens
  • Anonymous users can access the API (no user login required)
  • Tokens are cached server-side until near expiry

Prerequisites

Before starting, you need:

  1. Azure/Entra ID Access - Ability to register applications
  2. Public API Permissions - Admin must grant your app access to the Public API
  3. Environment Variable Access - Ability to configure .env.local

Setup Guide

Step 1: Use Your Existing Entra ID App Registration

The Public API uses the same Entra ID app registration as user authentication. You should already have:

  • ENTRA_TENANT_ID - Your Entra tenant GUID
  • ENTRA_CLIENT_ID - Your app registration client ID
  • ENTRA_CLIENT_SECRET - Your app registration secret

If you haven't set these up yet, see the Quickstart Guide.

Step 2: Add API Permissions

  1. Go to Azure Portal > Microsoft Entra ID > App registrations
  2. Select your existing app registration
  3. Go to API permissions
  4. Click Add a permission
  5. Select APIs my organization uses
  6. Find Enterprise AI Public API
  7. Select Application permissions (not Delegated)
  8. Select the required permissions
  9. Click Add permissions
  10. Click Grant admin consent (requires admin rights)

Step 3: Get the API Scope

The scope is the App ID URI of the Public API:

  • If Public API App ID URI is api://eai-public-api
  • Add this to your ENTRA_SCOPES

Contact your Enterprise AI administrator for the correct scope value.

Step 4: Configure Environment

Update your .env.local to include the API scope in ENTRA_SCOPES:

# =============================================================================
# Microsoft Entra ID Configuration
# =============================================================================

# Your Entra tenant and app registration
ENTRA_TENANT_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
ENTRA_TENANT_NAME=yourcompany.onmicrosoft.com
ENTRA_CLIENT_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
ENTRA_CLIENT_SECRET=your-secret-value

# OAuth scopes - include your API scope for client credentials flow
# The token service extracts api:// scopes automatically
ENTRA_SCOPES=email offline_access openid profile api://eai-public-api

# Public API base URL
BASE_URL_PUBLIC_API=https://test-api.myenterprise.ai

Note: The token service automatically extracts the api:// scope from ENTRA_SCOPES for client credentials flow.

Using the API

Client-Side: Calling Through the Proxy

All Public API calls go through the proxy at /api/eai/public/v3/...:

// Call any Public API endpoint through the proxy
const response = await fetch('/api/eai/public/v3/some/endpoint', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ data: 'value' }),
});

const data = await response.json();

Using the Address Lookup Hook

The template includes a ready-to-use address lookup hook:

import { useAddressLookup } from '@enterpriseaigroup/client';

function AddressSearch({ tenantId }: { tenantId: string }) {
const { suggestions, status, search } = useAddressLookup(
'/api/eai/public/v3/nsw/address-lookup',
3, // minimum characters before search
tenantId
);

return (
<input
type="text"
onChange={(e) => search(e.target.value)}
placeholder="Search address..."
/>
);
}

Available Endpoints

The proxy forwards all requests matching /api/eai/public/v3/* to the Public API:

Proxy RoutePublic API Endpoint
/api/eai/public/v3/nsw/address-lookup/v3/nsw/address-lookup
/api/eai/public/v3/your/endpoint/v3/your/endpoint

Security Best Practices

Secrets Management

  1. Never commit .env.local - It's gitignored by default
  2. Use environment variables in deployment - Configure in Vercel/Azure/etc.
  3. Rotate secrets regularly - Set calendar reminder for expiry
  4. Use Azure Key Vault for production deployments

Token Security

  1. Tokens stay server-side - Client never sees access tokens
  2. Automatic refresh - Token service handles expiry
  3. No refresh tokens exposed - Client credentials flow doesn't use them

Access Control Options

The proxy routes are public by default (no user login required). To require user authentication:

// In your proxy route, add auth check:
import { auth } from '@/auth';

export async function GET(request: NextRequest) {
const session = await auth();
if (!session) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
}
// ... proceed with proxy
}

Troubleshooting

"Failed to acquire token" Error

Causes:

  • Invalid client ID or secret
  • Wrong tenant ID
  • App not granted API permissions
  • Missing API scope in ENTRA_SCOPES

Solutions:

  1. Verify ENTRA_* values in .env.local match Azure portal
  2. Check if admin consent was granted for API permissions
  3. Verify app is registered in correct tenant
  4. Ensure ENTRA_SCOPES includes your api:// scope

"401 Unauthorized" from Public API

Causes:

  • Token scope doesn't match API expectations
  • API permissions not configured
  • Token expired (shouldn't happen with caching)

Solutions:

  1. Verify your API scope (e.g., api://eai-public-api) is in ENTRA_SCOPES
  2. Check if all required permissions are granted
  3. Clear token cache and retry

"CORS Error"

This shouldn't happen - The proxy runs server-side, so no CORS issues.

If you see CORS errors:

  1. You might be calling the Public API directly from browser (don't do this)
  2. Use the /api/eai/public/v3/... proxy routes instead

Debugging Token Issues

Check server logs for token acquisition:

# In development, look for these log messages:
[PublicAPI] Token acquisition failed: ...
[PublicAPI Proxy] Error: ...

Implementation Details

Token Service

The token service (src/lib/public-api-token.ts) handles:

  • Token acquisition using client credentials
  • In-memory caching with 5-minute expiry buffer
  • Automatic refresh when token nears expiry

Proxy Route

The proxy route (src/app/api/eai/public/v3/[...path]/route.ts) handles:

  • All HTTP methods (GET, POST, PUT, PATCH, DELETE)
  • Query parameter forwarding
  • Request body forwarding for POST/PUT/PATCH
  • Response status preservation

Next Steps

  • Review the token service implementation in src/lib/public-api-token.ts
  • Explore the proxy route in src/app/api/eai/public/v3/[...path]/route.ts
  • Check available hooks in packages/client/src/hooks/