Authentication
Secure your API calls with Bearer token authentication
Overview
AppHighway uses Bearer token authentication for all API endpoints. Each user can create multiple API tokens with custom names, scopes, and rate limits.
Multi-Token Support
Create multiple API tokens for different environments (production, staging, development) or applications.
Token Scopes
Control which APIs each token can access. Useful for limiting permissions for specific use cases.
Rate Limiting
Each token has its own rate limit (default: 60 requests per minute). Customize limits based on your needs.
Optional Expiration
Set expiration dates for tokens to enhance security. Tokens without expiration dates remain valid indefinitely.
Getting Started
Follow these steps to start using AppHighway tools with authentication:
1. Sign up or Sign in
Create an AppHighway account or sign in to your existing account via the dashboard.
2. Create an API Token
Navigate to the Tokens page in your dashboard and create a new API token. Give it a descriptive name (e.g., 'Production Server', 'Mobile App').
3. Use Your Token
Include your API token in the Authorization header of every API request as a Bearer token.
Security Warning
Creating API Tokens
Step-by-step guide to creating and managing your API tokens
Creating a Token via Dashboard
- Navigate to your AppHighway Dashboard
- Click on 'Tokens' in the sidebar navigation
- Click the 'Create New Token' button
- Enter a descriptive name for your token (e.g., 'Production Server', 'Mobile App')
- Select the API scopes (permissions) for this token
- Set the rate limit (default: 60 requests per minute)
- Optionally set an expiration date for enhanced security
- Click 'Create Token' and immediately copy the generated token to a secure location
Important: Save Your Token Now
Token Naming Best Practices
Use clear, descriptive names to identify the purpose and environment of each token:
Token Scopes
Control which APIs your token can access:
Making Authenticated Requests
Include your API token in the Authorization header using the Bearer scheme:
Using cURL
curl -X POST https://apphighway.com/api/v1/structify \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"text": "John Doe is 35 years old and lives in New York",
"schema": {
"name": "string",
"age": "number",
"city": "string"
}
}'Using Node.js
import fetch from 'node-fetch';
const API_TOKEN = 'your_api_token_here';
const API_URL = 'https://apphighway.com/api/v1';
async function callAPI(endpoint, data) {
const response = await fetch(`${API_URL}/${endpoint}`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
});
if (!response.ok) {
throw new Error(`API call failed: ${response.statusText}`);
}
return response.json();
}
// Example: Use Structify API
const result = await callAPI('structify', {
text: 'John Doe is 35 years old',
schema: { name: 'string', age: 'number' }
});
console.log(result);Using Python
import requests
API_TOKEN = 'your_api_token_here'
API_URL = 'https://apphighway.com/api/v1'
def call_api(endpoint, data):
headers = {
'Authorization': f'Bearer {API_TOKEN}',
'Content-Type': 'application/json'
}
response = requests.post(
f'{API_URL}/{endpoint}',
headers=headers,
json=data
)
response.raise_for_status()
return response.json()
# Example: Use Structify API
result = call_api('structify', {
'text': 'John Doe is 35 years old',
'schema': {'name': 'string', 'age': 'number'}
})
print(result)Advanced Usage Examples
Production-ready examples with error handling, retry logic, and best practices
TypeScript Client with Error Handling
A robust TypeScript client with type safety and comprehensive error handling for production use
const API_TOKEN = process.env.APPHIGHWAY_API_TOKEN!;
const API_URL = 'https://apphighway.com/api/v1';
interface APIError {
error: {
code: string;
message: string;
details: string;
};
}
interface APIResponse<T> {
status: string;
data: T;
pointsUsed: number;
remainingPoints: number;
}
async function callAPI<T>(
endpoint: string,
data: Record<string, unknown>
): Promise<APIResponse<T>> {
const response = await fetch(`${API_URL}/${endpoint}`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
});
const result = await response.json();
if (!response.ok) {
const apiError = result as APIError;
if (apiError?.error?.code === 'INSUFFICIENT_POINTS') {
throw new Error('Insufficient points. Please purchase more points.');
}
if (apiError?.error?.code === 'UNAUTHORIZED') {
throw new Error('Invalid API token. Please check your credentials.');
}
if (response.status === 429) {
throw new Error('Rate limit exceeded. Please wait before retrying.');
}
throw new Error(apiError?.error?.message || 'API request failed');
}
return result as APIResponse<T>;
}
// Usage
const result = await callAPI('structify', {
text: 'John Doe is 35 years old',
schema: { name: 'string', age: 'number' }
});
console.log(result.data);
console.log(`Points used: ${result.pointsUsed}`);Implementing Retry Logic
Handle transient errors and rate limits with exponential backoff retry strategy
import fetch from 'node-fetch';
const API_TOKEN = process.env.APPHIGHWAY_API_TOKEN;
const API_URL = 'https://apphighway.com/api/v1';
async function callAPIWithRetry(
endpoint: string,
data: object,
maxRetries = 3
) {
let lastError;
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
const response = await fetch(`${API_URL}/${endpoint}`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
});
// Don't retry on client errors (4xx except 429)
if (response.status >= 400 && response.status < 500 && response.status !== 429) {
const error = await response.json();
throw new Error(`API Error: ${error.error.message}`);
}
// Retry on server errors (5xx) or rate limits (429)
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
return await response.json();
} catch (error) {
lastError = error;
if (attempt < maxRetries - 1) {
// Exponential backoff: 1s, 2s, 4s
const delay = Math.pow(2, attempt) * 1000;
console.log(`Retry attempt ${attempt + 1} after ${delay}ms`);
await new Promise(resolve => setTimeout(resolve, delay));
}
}
}
throw lastError;
}
// Usage
const result = await callAPIWithRetry('structify', {
text: 'John Doe is 35 years old',
schema: { name: 'string', age: 'number' }
});Go Implementation
Production-ready Go client with proper error handling and HTTP best practices
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
)
const apiURL = "https://apphighway.com/api/v1"
type APIClient struct {
Token string
HTTPClient *http.Client
}
type APIError struct {
Error struct {
Code string `json:"code"`
Message string `json:"message"`
Details string `json:"details"`
} `json:"error"`
}
func NewClient(token string) *APIClient {
return &APIClient{
Token: token,
HTTPClient: &http.Client{},
}
}
func (c *APIClient) Call(endpoint string, data interface{}) ([]byte, error) {
jsonData, err := json.Marshal(data)
if err != nil {
return nil, fmt.Errorf("failed to marshal data: %w", err)
}
req, err := http.NewRequest(
"POST",
fmt.Sprintf("%s/%s", apiURL, endpoint),
bytes.NewBuffer(jsonData),
)
if err != nil {
return nil, fmt.Errorf("failed to create request: %w", err)
}
req.Header.Set("Authorization", "Bearer "+c.Token)
req.Header.Set("Content-Type", "application/json")
resp, err := c.HTTPClient.Do(req)
if err != nil {
return nil, fmt.Errorf("request failed: %w", err)
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("failed to read response: %w", err)
}
if resp.StatusCode != http.StatusOK {
var apiErr APIError
if err := json.Unmarshal(body, &apiErr); err == nil {
return nil, fmt.Errorf("API error: %s", apiErr.Error.Message)
}
return nil, fmt.Errorf("HTTP %d: %s", resp.StatusCode, string(body))
}
return body, nil
}
func main() {
client := NewClient(os.Getenv("APPHIGHWAY_API_TOKEN"))
data := map[string]interface{}{
"text": "John Doe is 35 years old",
"schema": map[string]string{
"name": "string",
"age": "number",
},
}
result, err := client.Call("structify", data)
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Printf("Result: %s\n", result)
}Token Management
Best practices for managing your API tokens:
Descriptive Names
Use clear, descriptive names for your tokens to identify their purpose and environment. Examples:
Token Rotation
Regularly rotate your API tokens for enhanced security. Create a new token, update your applications, and delete the old token.
Immediate Revocation
If a token is compromised, immediately revoke it from your dashboard to prevent unauthorized access.
Error Handling
Common authentication-related errors and how to handle them:
Unauthorized
Your API token is invalid, expired, or missing. Verify that you're sending the correct token in the Authorization header.
{
"error": {
"code": "UNAUTHORIZED",
"message": "Invalid or expired API token",
"details": "The provided token is not valid or has expired"
}
}Payment Required (Insufficient Points)
Your account doesn't have enough points to make this API call. Purchase more points to continue.
{
"error": {
"code": "INSUFFICIENT_POINTS",
"message": "Insufficient points. Required: 3, Available: 1",
"details": "Please purchase more points to continue using the API"
}
}Too Many Requests
You've exceeded the rate limit for your token. Wait before making additional requests or upgrade your rate limit.
Token Security Best Practices
Critical security guidelines for protecting your API tokens and preventing unauthorized access
Secure Token Storage
Never expose tokens in your codebase or version control
Use Environment Variables
Store tokens in environment variables (.env files) and never commit them to git. Add .env to your .gitignore file.
Use Secrets Management Systems
For production environments, use dedicated secrets management solutions like AWS Secrets Manager, HashiCorp Vault, or Azure Key Vault.
Never Hardcode Tokens
Avoid hardcoding tokens directly in source code, configuration files, or client-side applications.
Never Expose in Client-Side Code
API tokens should only be used in server-side code. Never include them in frontend JavaScript, mobile apps, or any client-facing code.
Token Rotation
Regularly rotate tokens to minimize security risks
Rotate Every 90 Days
Implement a regular rotation schedule (every 90 days recommended) to limit the exposure window if a token is compromised.
Zero-Downtime Rotation Process
Create a new token, update your applications to use both tokens temporarily, then remove the old token once all systems are migrated.
Automate Rotation
Use automation tools and CI/CD pipelines to streamline the token rotation process and reduce manual errors.
Access Control & Scoping
Implement the principle of least privilege
Use Minimal Scopes
Only grant access to the specific APIs your application needs. Avoid using tokens with full access unless absolutely necessary.
Separate Tokens per Environment
Use different tokens for production, staging, and development environments. Never reuse production tokens in lower environments.
One Token per Application
Create separate tokens for each application or service. This makes it easier to track usage and revoke access when needed.
Monitoring & Detection
Detect and respond to suspicious activity
Monitor Token Usage
Regularly review token usage in your dashboard. Look for unexpected spikes, unusual API calls, or access from unfamiliar locations.
Set Up Alerts
Configure alerts for unusual activity patterns, such as rate limit violations, failed authentication attempts, or API calls from unexpected IPs.
Implement Comprehensive Logging
Log all API requests with timestamps, endpoints called, and response codes. This helps with debugging and security audits.
Incident Response
Act quickly if a token is compromised
Revoke Compromised Tokens Immediately
If you suspect a token has been exposed or compromised, revoke it immediately from your dashboard to prevent unauthorized access.
Assess the Impact
Review API usage logs to determine what actions were taken with the compromised token and assess any potential data exposure.
Create a New Token
After revoking a compromised token, create a new token with appropriate scopes and update your applications.
Review Points Usage
Check your points balance and usage history. Unauthorized API calls may have consumed points. Contact support if you notice fraudulent usage.
Secure Transport
Protect tokens during transmission
Always Use HTTPS
Only make API calls over HTTPS to encrypt tokens in transit. Never send tokens over unencrypted HTTP connections.
Verify TLS Certificates
Ensure your HTTP client verifies SSL/TLS certificates to prevent man-in-the-middle attacks.
Avoid Logging Tokens
Never log full API tokens in application logs, error messages, or debugging output. If logging is necessary, redact or mask the token value.
Compliance & Governance
Maintain compliance with security standards
Document Token Usage
Maintain an inventory of all active tokens, their purposes, owners, and expiration dates.
Regular Access Reviews
Periodically review all active tokens and revoke those that are no longer needed or belong to former team members.
Set Expiration Dates
For temporary use cases or short-term projects, set token expiration dates to automatically limit their lifetime.
Best Practices
Follow these security best practices when using AppHighway tools:
- Store API tokens in environment variables, never hardcode them in your source code
- Use different tokens for different environments (production, staging, development)
- Set appropriate scopes to limit token permissions to only the APIs you need
- Implement token rotation every 90 days for enhanced security
- Monitor token usage in your dashboard to detect suspicious activity
- Set expiration dates for tokens that are only needed temporarily