Documentation Index
Fetch the complete documentation index at: https://noorle.com/docs/llms.txt
Use this file to discover all available pages before exploring further.
Noorle APIs support three authentication methods: API Keys, JWT Bearer tokens, and OAuth device flow.
Authentication Methods
1. API Key (Simplest)
Use X-API-Key header for REST API calls.
Generate API Key:
# Via Console: Settings → API Keys → Create
# Via CLI:
noorle api-key generate
# Output: ak-a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4s9t0u1v2w3x4y5z6
Usage:
curl -X GET https://api.noorle.com/v1/capabilities \
-H "X-API-Key: ak-a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4s9t0u1v2w3x4y5z6"
Alternative Headers:
API keys accept these headers (in order of preference):
X-API-Key: ak-a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4s9t0u1v2w3x4y5z6
API-Key: ak-a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4s9t0u1v2w3x4y5z6
Authorization: ApiKey ak-a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4s9t0u1v2w3x4y5z6
Best for:
- CLI tools
- Service-to-service authentication
- Simple scripts
- Development/testing
Security:
- Treat as a password
- Rotate periodically
- Revoke when compromised
- Scope to specific API keys (read-only vs full access)
2. Bearer Token (OAuth)
Use Authorization: Bearer header with JWT token.
Get Token (OAuth Device Flow):
# Step 1: Request device code
noorle login
# Output:
# Please visit: https://console.noorle.com/oauth/device/verify
# Code: XYZABC
# Step 2: User approves on console
# Step 3: CLI polls for token
# Token stored in ~/.noorle/token.json
Manual Token Exchange:
# Request device code
curl -X POST https://api.noorle.com/oauth/device/authorize \
-H "Content-Type: application/json" \
-d '{
"client_id": "noorle-cli",
"scope": "api"
}'
# Response:
# {
# "device_code": "ABCD1234",
# "user_code": "WXYZ",
# "verification_uri": "https://console.noorle.com/oauth/device/verify",
# "expires_in": 1800
# }
# User approves at verification_uri
# Poll for token
curl -X POST https://api.noorle.com/oauth/token \
-H "Content-Type: application/json" \
-d '{
"grant_type": "urn:ietf:params:oauth:grant-type:device_code",
"device_code": "ABCD1234",
"client_id": "noorle-cli"
}'
# Response:
# {
# "access_token": "eyJhbGc...",
# "token_type": "Bearer",
# "expires_in": 3600
# }
Usage:
curl -X GET https://api.noorle.com/v1/capabilities \
-H "Authorization: Bearer eyJhbGc..."
Token Refresh:
curl -X POST https://api.noorle.com/oauth/token \
-H "Content-Type: application/json" \
-d '{
"grant_type": "refresh_token",
"refresh_token": "refresh_token_value",
"client_id": "noorle-cli"
}'
# Response with new access_token
Best for:
- User-initiated workflows
- Web applications
- Mobile apps
- Delegated access
Token Structure (JWT):
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Decoded payload:
{
"sub": "user-id",
"account_id": "account-id",
"scope": "api",
"iat": 1516239022,
"exp": 1516242622
}
3. Service Account Token
For server-to-server authentication with extended expiry.
Create Service Account:
noorle service-account create --name "integration-bot"
# Output:
# Service Account ID: sa_1234567890
# Client ID: noorle-sa-1234567890
# Client Secret: secret_abcdefg
# Store secret securely (shown only once)
Get Token:
curl -X POST https://api.noorle.com/oauth/token \
-H "Content-Type: application/json" \
-d '{
"grant_type": "client_credentials",
"client_id": "noorle-sa-1234567890",
"client_secret": "secret_abcdefg",
"scope": "api"
}'
# Response:
# {
# "access_token": "eyJhbGc...",
# "token_type": "Bearer",
# "expires_in": 86400
# }
Usage:
curl -X GET https://api.noorle.com/v1/capabilities \
-H "Authorization: Bearer eyJhbGc..."
Best for:
- Automation and CI/CD
- Server-to-server communication
- Scheduled jobs
- Long-lived integrations
MCP Gateway Authentication
MCP Gateways require OAuth token or API key.
Connect via Bearer Token:
curl -N -H "Authorization: Bearer eyJhbGc..." \
https://mcp-{gateway-id}.noorle.com/sse \
--no-buffer --raw
Via Query Parameter (limited security):
curl -N https://mcp-{gateway-id}.noorle.com/sse?access_token=eyJhbGc... \
--no-buffer --raw
A2A Gateway Authentication
A2A Gateways require OAuth token.
WebSocket Connection:
const token = "eyJhbGc...";
const url = `wss://agent-{gateway-id}.noorle.com/ws?token=${token}`;
const ws = new WebSocket(url);
ws.onmessage = (event) => {
const message = JSON.parse(event.data);
// Handle message
};
HTTP with Bearer:
curl -X POST https://agent-{gateway-id}.noorle.com/message/send \
-H "Authorization: Bearer eyJhbGc..." \
-H "Content-Type: application/json" \
-d '{"message": "Hello"}'
Token Management
Expiration and Refresh
Tokens expire after set duration:
{
"access_token": "...",
"expires_in": 3600,
"refresh_token": "..."
}
Refresh before expiry:
curl -X POST https://api.noorle.com/oauth/token \
-H "Content-Type: application/json" \
-d '{
"grant_type": "refresh_token",
"refresh_token": "refresh_...",
"client_id": "noorle-cli"
}'
Token Revocation
Revoke tokens when no longer needed:
noorle token revoke eyJhbGc...
# Or via API
curl -X POST https://api.noorle.com/oauth/token/revoke \
-H "Content-Type: application/json" \
-d '{
"token": "eyJhbGc..."
}'
Checking Token Status
Validate token before use:
curl -X POST https://api.noorle.com/oauth/introspect \
-H "Content-Type: application/json" \
-d '{
"token": "eyJhbGc..."
}'
# Response:
# {
# "active": true,
# "scope": "api",
# "expires_at": 1711123200
# }
Authentication Examples
Python
import requests
from datetime import datetime, timedelta
class NoorleAuth:
def __init__(self, api_key=None, token=None):
self.api_key = api_key
self.token = token
self.token_expiry = None
def headers(self):
if self.api_key:
return {"X-API-Key": self.api_key}
elif self.token:
return {"Authorization": f"Bearer {self.token}"}
return {}
def refresh_token(self, client_id, client_secret):
# Refresh logic
pass
# Usage
auth = NoorleAuth(api_key="ak-a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4s9t0u1v2w3x4y5z6")
resp = requests.get(
"https://api.noorle.com/v1/capabilities",
headers=auth.headers()
)
JavaScript/TypeScript
import fetch from "node-fetch";
class NoorleAuth {
constructor(apiKey?: string, token?: string) {
this.apiKey = apiKey;
this.token = token;
}
headers() {
if (this.apiKey) {
return { "X-API-Key": this.apiKey };
}
if (this.token) {
return { Authorization: `Bearer ${this.token}` };
}
return {};
}
}
// Usage
const auth = new NoorleAuth(
undefined,
"eyJhbGc..."
);
const response = await fetch(
"https://api.noorle.com/v1/capabilities",
{
headers: auth.headers(),
}
);
cURL
# With API Key
curl -H "X-API-Key: ak-a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4s9t0u1v2w3x4y5z6" \
https://api.noorle.com/v1/capabilities
# With Bearer Token
curl -H "Authorization: Bearer eyJhbGc..." \
https://api.noorle.com/v1/capabilities
# With Device Flow (CLI handles this)
noorle login
noorle api-call GET /v1/capabilities
Security Best Practices
Protect API Keys
- ❌ Don’t commit to version control
- ✅ Use
.env or secrets management
- ❌ Don’t hardcode in code
- ✅ Load from environment
- ❌ Don’t log or display
- ✅ Rotate regularly
# .env file
NOORLE_API_KEY=ak-a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4s9t0u1v2w3x4y5z6
# Code
import os
api_key = os.getenv("NOORLE_API_KEY")
Token Scope
Use minimal scopes:
# Generate token with specific scope
noorle oauth-token generate \
--scope "read:plugins" \
--scope "write:agents"
# Limits what token can do
TLS/HTTPS
Always use HTTPS:
# ✅ Correct
curl https://api.noorle.com/...
# ❌ Never use HTTP
curl http://api.noorle.com/... # Insecure!
Audit Access
Monitor authentication:
# View login history
noorle audit logs --filter auth
# Revoke compromised tokens
noorle token revoke TOKEN_VALUE
# Check active sessions
noorle session list
Troubleshooting
“Invalid API Key”
- Check key starts with
ak-
- Verify key hasn’t been revoked
- Regenerate if unsure
“Token Expired”
- Refresh using refresh_token
- Re-authenticate if expired
“Insufficient Permissions”
- Check token/key scope
- Ensure account has access
- Contact admin if needed
Next Steps