AGIN CloudCloud
API clients

API Client

Learn how to authenticate and make requests to the Agin Cloud API using Bearer token authentication

What is an API Client?

An API client is any application or code that makes HTTP requests to interact with the Agin Cloud API. Unlike SDKs (Software Development Kits) that provide pre-built methods, you'll be making direct HTTP requests using your preferred HTTP client library.

Authentication Method

Agin Cloud uses Bearer token authentication. Your API key serves as the bearer token that you include in the Authorization header of every request.

Getting Your API Key

Before you can make requests to the Agin Cloud API, you need to obtain an API key.

Log in to Agin Cloud Dashboard

Navigate to https://agin.cloud and sign in with your credentials.

Access API Settings

From the dashboard, click on Settings in the sidebar, then select API Keys.

Generate New API Key

Click the Generate New Key button. You'll be prompted to:

  • Provide a descriptive name for your key (e.g., "Production App", "Development")
  • Select the appropriate permissions/scopes
  • Set an expiration date (optional but recommended)

Save Your API Key

Important

Copy your API key immediately. For security reasons, you won't be able to see it again after closing this dialog.

Store your API key securely using environment variables or a secrets manager. Never commit API keys to version control.

API Key Format

Agin Cloud API keys follow this format:

agin_live_1234567890abcdefghijklmnopqrstuvwxyz
  • agin_ - Prefix identifying it as an Agin Cloud key
  • live_ or test_ - Environment identifier
  • Random alphanumeric string - Your unique key

Setting Up Your Environment

Environment Variables

Create a .env file in your project root:

.env
AGIN_API_KEY=agin_live_your_api_key_here
AGIN_API_URL=https://api.agin.cloud/v1

Use agin_test_ keys for development and testing environments.

Add to .gitignore

Ensure your .env file is not committed to version control:

.gitignore
.env
.env.local
.env.*.local

Bearer Token Authentication

The Agin Cloud API uses Bearer token authentication. Your API key is used directly as the bearer token.

How It Works

Include your API key in the Authorization header of every request:

Authorization: Bearer agin_live_your_api_key_here

This header must be included in all requests to the Agin Cloud API.

Making Requests

You can use any HTTP client library to make requests. Here are examples with popular options:

Using fetch (Built-in)

fetch-example.ts
const response = await fetch('https://api.agin.cloud/v1/resources', {
  method: 'GET',
  headers: {
    'Authorization': `Bearer ${process.env.AGIN_API_KEY}`,
    'Content-Type': 'application/json',
  },
});

if (!response.ok) {
  throw new Error(`HTTP error! status: ${response.status}`);
}

const data = await response.json();
console.log(data);
create-resource.ts
const response = await fetch('https://api.agin.cloud/v1/resources', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${process.env.AGIN_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    name: 'My Resource',
    type: 'compute',
    config: {
      cpu: 2,
      memory: '4GB',
    },
  }),
});

if (!response.ok) {
  throw new Error(`HTTP error! status: ${response.status}`);
}

const resource = await response.json();
console.log('Created:', resource.id);
update-resource.ts
const response = await fetch('https://api.agin.cloud/v1/resources/resource_123', {
  method: 'PUT',
  headers: {
    'Authorization': `Bearer ${process.env.AGIN_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    name: 'Updated Name',
    config: {
      cpu: 4,
      memory: '8GB',
    },
  }),
});

if (!response.ok) {
  throw new Error(`HTTP error! status: ${response.status}`);
}

const updated = await response.json();
console.log('Updated:', updated);
delete-resource.ts
const response = await fetch('https://api.agin.cloud/v1/resources/resource_123', {
  method: 'DELETE',
  headers: {
    'Authorization': `Bearer ${process.env.AGIN_API_KEY}`,
  },
});

if (!response.ok) {
  throw new Error(`HTTP error! status: ${response.status}`);
}

console.log('Deleted successfully');

Using axios

First, install axios:

npm install axios

Then make requests:

axios-get.ts
import axios from 'axios';

const client = axios.create({
  baseURL: 'https://api.agin.cloud/v1',
  headers: {
    'Authorization': `Bearer ${process.env.AGIN_API_KEY}`,
  },
});

const response = await client.get('/resources');
console.log(response.data);
axios-post.ts
import axios from 'axios';

const client = axios.create({
  baseURL: 'https://api.agin.cloud/v1',
  headers: {
    'Authorization': `Bearer ${process.env.AGIN_API_KEY}`,
  },
});

const response = await client.post('/resources', {
  name: 'My Resource',
  type: 'compute',
  config: {
    cpu: 2,
    memory: '4GB',
  },
});

console.log('Created:', response.data.id);
axios-put.ts
const response = await client.put('/resources/resource_123', {
  name: 'Updated Name',
  config: {
    cpu: 4,
    memory: '8GB',
  },
});

console.log('Updated:', response.data);
axios-delete.ts
const response = await client.delete('/resources/resource_123');
console.log('Deleted successfully');

Creating a Reusable Client

Create a simple wrapper to avoid repeating authentication:

lib/agin-client.ts
class AginClient {
  private baseURL: string;
  private apiKey: string;

  constructor(apiKey: string, baseURL = 'https://api.agin.cloud/v1') {
    this.baseURL = baseURL;
    this.apiKey = apiKey;
  }

  private async request(
    endpoint: string,
    options: RequestInit = {}
  ) {
    const url = `${this.baseURL}${endpoint}`;
    
    const response = await fetch(url, {
      ...options,
      headers: {
        'Authorization': `Bearer ${this.apiKey}`,
        'Content-Type': 'application/json',
        ...options.headers,
      },
    });

    if (!response.ok) {
      const error = await response.json().catch(() => ({}));
      throw new Error(error.message || `HTTP ${response.status}`);
    }

    return response.json();
  }

  async get(endpoint: string) {
    return this.request(endpoint, { method: 'GET' });
  }

  async post(endpoint: string, data: any) {
    return this.request(endpoint, {
      method: 'POST',
      body: JSON.stringify(data),
    });
  }

  async put(endpoint: string, data: any) {
    return this.request(endpoint, {
      method: 'PUT',
      body: JSON.stringify(data),
    });
  }

  async delete(endpoint: string) {
    return this.request(endpoint, { method: 'DELETE' });
  }
}

// Export configured instance
export const aginClient = new AginClient(
  process.env.AGIN_API_KEY!
);

Usage:

app.ts
import { aginClient } from './lib/agin-client';

// GET request
const resources = await aginClient.get('/resources');

// POST request
const newResource = await aginClient.post('/resources', {
  name: 'My Resource',
  type: 'compute',
});

// PUT request
const updated = await aginClient.put('/resources/resource_123', {
  name: 'Updated Name',
});

// DELETE request
await aginClient.delete('/resources/resource_123');

Error Handling

Handle different HTTP status codes appropriately:

error-handling.ts
async function makeRequest() {
  try {
    const response = await fetch('https://api.agin.cloud/v1/resources', {
      headers: {
        'Authorization': `Bearer ${process.env.AGIN_API_KEY}`,
      },
    });

    // Handle different status codes
    switch (response.status) {
      case 200:
      case 201:
        return await response.json();
      
      case 400:
        const validationError = await response.json();
        console.error('Validation error:', validationError.errors);
        throw new Error('Invalid request');
      
      case 401:
        console.error('Unauthorized: Check your API key');
        throw new Error('Authentication failed');
      
      case 403:
        console.error('Forbidden: Insufficient permissions');
        throw new Error('Access denied');
      
      case 404:
        console.error('Resource not found');
        throw new Error('Not found');
      
      case 429:
        const retryAfter = response.headers.get('Retry-After');
        console.error(`Rate limited. Retry after ${retryAfter} seconds`);
        throw new Error('Rate limit exceeded');
      
      case 500:
      case 502:
      case 503:
      case 504:
        console.error('Server error');
        throw new Error('Server error');
      
      default:
        throw new Error(`Unexpected status: ${response.status}`);
    }
  } catch (error) {
    console.error('Request failed:', error);
    throw error;
  }
}

Framework Integration

Next.js App Router (API Route)

app/api/resources/route.ts
import { NextResponse } from 'next/server';

export async function GET(request: Request) {
  try {
    const response = await fetch('https://api.agin.cloud/v1/resources', {
      headers: {
        'Authorization': `Bearer ${process.env.AGIN_API_KEY}`,
        'Content-Type': 'application/json',
      },
      // Important for server-side caching
      next: { revalidate: 60 }, // Revalidate every 60 seconds
    });

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    const data = await response.json();
    return NextResponse.json(data);
  } catch (error) {
    return NextResponse.json(
      { error: 'Failed to fetch resources' },
      { status: 500 }
    );
  }
}

export async function POST(request: Request) {
  try {
    const body = await request.json();
    
    const response = await fetch('https://api.agin.cloud/v1/resources', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${process.env.AGIN_API_KEY}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(body),
    });

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    const data = await response.json();
    return NextResponse.json(data);
  } catch (error) {
    return NextResponse.json(
      { error: 'Failed to create resource' },
      { status: 500 }
    );
  }
}

Next.js Server Component

app/resources/page.tsx
async function getResources() {
  const response = await fetch('https://api.agin.cloud/v1/resources', {
    headers: {
      'Authorization': `Bearer ${process.env.AGIN_API_KEY}`,
    },
    next: { revalidate: 3600 }, // Cache for 1 hour
  });

  if (!response.ok) {
    throw new Error('Failed to fetch resources');
  }

  return response.json();
}

export default async function ResourcesPage() {
  const resources = await getResources();
  
  return (
    <div>
      <h1>Resources</h1>
      <ul>
        {resources.data.map((resource: any) => (
          <li key={resource.id}>{resource.name}</li>
        ))}
      </ul>
    </div>
  );
}

React Client Component

components/ResourcesList.tsx
'use client';

import { useEffect, useState } from 'react';

export function ResourcesList() {
  const [resources, setResources] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  
  useEffect(() => {
    async function fetchResources() {
      try {
        // Call your API route, not Agin API directly
        const response = await fetch('/api/resources');
        
        if (!response.ok) {
          throw new Error('Failed to fetch');
        }
        
        const data = await response.json();
        setResources(data.data || []);
      } catch (err) {
        setError(err instanceof Error ? err.message : 'An error occurred');
      } finally {
        setLoading(false);
      }
    }
    
    fetchResources();
  }, []);
  
  if (loading) return <div>Loading...</div>;
  if (error) return <div>Error: {error}</div>;
  
  return (
    <ul>
      {resources.map((resource: any) => (
        <li key={resource.id}>{resource.name}</li>
      ))}
    </ul>
  );
}

Security Best Practice

Never expose your Agin API key in client-side code. Always make API calls from your backend (API routes, server components, or server functions) where environment variables are secure.

Express.js

server.ts
import express from 'express';

const app = express();
app.use(express.json());

app.get('/api/resources', async (req, res) => {
  try {
    const response = await fetch('https://api.agin.cloud/v1/resources', {
      headers: {
        'Authorization': `Bearer ${process.env.AGIN_API_KEY}`,
      },
    });

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    const data = await response.json();
    res.json(data);
  } catch (error) {
    res.status(500).json({ 
      error: 'Failed to fetch resources' 
    });
  }
});

app.post('/api/resources', async (req, res) => {
  try {
    const response = await fetch('https://api.agin.cloud/v1/resources', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${process.env.AGIN_API_KEY}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(req.body),
    });

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    const data = await response.json();
    res.json(data);
  } catch (error) {
    res.status(500).json({ 
      error: 'Failed to create resource' 
    });
  }
});

app.listen(3000, () => {
  console.log('Server running on port 3000');
});

Security Best Practices

1. Store API Keys Securely

.env
# ✅ Good - Use environment variables
AGIN_API_KEY=agin_live_xxxxx
// ❌ Bad - Never hardcode
const apiKey = 'agin_live_xxxxx';

2. Use Different Keys for Different Environments

.env.development
AGIN_API_KEY=agin_test_xxxxx
.env.production
AGIN_API_KEY=agin_live_xxxxx

3. Never Expose Keys Client-Side

// ❌ Bad - API key exposed in browser
async function clientSideRequest() {
  const response = await fetch('https://api.agin.cloud/v1/resources', {
    headers: {
      'Authorization': `Bearer ${process.env.NEXT_PUBLIC_AGIN_API_KEY}`, // ❌
    },
  });
}

// ✅ Good - Use API routes
async function clientSideRequest() {
  const response = await fetch('/api/resources'); // ✅
}

4. Implement Rate Limiting

Respect the API's rate limits and implement exponential backoff for retries.

5. Monitor API Usage

Log requests for debugging and monitoring:

const startTime = Date.now();

const response = await fetch(url, options);

const duration = Date.now() - startTime;
console.log(`API Request: ${method} ${url} - ${response.status} (${duration}ms)`);

Rate Limits

Agin Cloud API has the following rate limits:

PlanRequests per Hour
Standard1,000
Pro10,000
EnterpriseCustom

Handling Rate Limits

Check the response headers for rate limit information:

const response = await fetch(url, options);

console.log('Rate Limit:', response.headers.get('X-RateLimit-Limit'));
console.log('Remaining:', response.headers.get('X-RateLimit-Remaining'));
console.log('Reset:', response.headers.get('X-RateLimit-Reset'));

if (response.status === 429) {
  const retryAfter = response.headers.get('Retry-After');
  console.log(`Rate limited. Retry after ${retryAfter} seconds`);
}

Troubleshooting

Authentication Failed (401)

Possible causes:

  • Invalid API key
  • Expired API key
  • Missing Authorization header
  • Using test key in production

Solution:

  • Verify your API key is correct
  • Ensure the Authorization header format is: Bearer YOUR_API_KEY
  • Check you're using the right environment key

Forbidden (403)

Possible causes:

  • Insufficient permissions for the operation
  • API key doesn't have required scope

Solution:

  • Check the permissions assigned to your API key
  • Generate a new key with appropriate permissions

Not Found (404)

Possible causes:

  • Incorrect endpoint URL
  • Resource doesn't exist
  • Typo in resource ID

Solution:

  • Verify the endpoint URL
  • Check the resource ID is correct
  • Consult the API reference for correct endpoints

Rate Limit Exceeded (429)

Solution:

  • Implement retry logic with exponential backoff
  • Reduce request frequency
  • Upgrade to a higher tier plan

Next Steps