Secure your API calls with Bearer token authentication
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.
Follow these steps to start using AppHighway APIs with authentication:
Create an AppHighway account or sign in to your existing account via the dashboard.
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').
Include your API token in the Authorization header of every API request as a Bearer token.
Step-by-step guide to creating and managing your API tokens
Use clear, descriptive names to identify the purpose and environment of each token:
Control which APIs your token can access:
Include your API token in the Authorization header using the Bearer scheme:
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"
}
}'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);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)Production-ready examples with error handling, retry logic, and best practices
A robust TypeScript client with type safety and comprehensive error handling for production use
import axios, { AxiosError } from 'axios';
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;
};
}
class AppHighwayClient {
private token: string;
private baseURL: string;
constructor(token: string, baseURL = API_URL) {
this.token = token;
this.baseURL = baseURL;
}
async call<T = unknown>(
endpoint: string,
data: Record<string, unknown>
): Promise<T> {
try {
const response = await axios.post<T>(
`${this.baseURL}/${endpoint}`,
data,
{
headers: {
'Authorization': `Bearer ${this.token}`,
'Content-Type': 'application/json',
},
}
);
return response.data;
} catch (error) {
if (axios.isAxiosError(error)) {
const apiError = error.response?.data 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 (error.response?.status === 429) {
throw new Error('Rate limit exceeded. Please wait before retrying.');
}
}
throw error;
}
}
}
// Usage
const client = new AppHighwayClient(API_TOKEN);
const result = await client.call('structify', {
text: 'John Doe is 35 years old',
schema: { name: 'string', age: 'number' }
});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' }
});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)
}Best practices for managing your API tokens:
Use clear, descriptive names for your tokens to identify their purpose and environment. Examples:
Regularly rotate your API tokens for enhanced security. Create a new token, update your applications, and delete the old token.
If a token is compromised, immediately revoke it from your dashboard to prevent unauthorized access.
Common authentication-related errors and how to handle them:
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"
}
}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"
}
}You've exceeded the rate limit for your token. Wait before making additional requests or upgrade your rate limit.
Critical security guidelines for protecting your API tokens and preventing unauthorized access
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.
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.
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.
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.
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.
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.
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.
Follow these security best practices when using AppHighway APIs: