ScriptForge API Documentation
Base URL: https://autherx.com/s/v1/
Last Updated: 2025-10-26
API Version: 1.0
Table of Contents
Overview
ScriptForge is a powerful API for managing Lua scripts with built-in version control, access management, and metadata tracking. Each script is uniquely identified by a 14-16 character hexadecimal filename (e.g., b9143ea7cf028d.lua).
Key Features
- 🔐 Secure Authentication - API key-based authentication
- 📝 Version Control - Automatic versioning with rollback support
- 🔒 Script Locking - Prevent accidental modifications
- 🏷️ Tagging System - Organize scripts with custom tags
- 👁️ Visibility Control - Public or private scripts
- 🗑️ Soft Delete - Recoverable deletion system
- 📊 Audit Logging - Complete activity tracking
Limits
| Feature | Limit |
|---|---|
| Max file size | 15 MB |
| Max scripts per service | 400 |
| Default rate limit | 60 requests/minute |
| Filename format | ^[a-f0-9]{14,16}\.lua$ |
Authentication
All API requests require authentication using an API key in the request header.
Header Format
Authorization: Bearer YOUR_API_KEY_HERE
Getting Your API Key
- Log in to your autherx dashboard
- Navigate to Service → API Keys
- Create a new API key or copy an existing one
- Store it securely (never expose it in client-side code)
Example Request
fetch('https://autherx.com/s/v1/scripts', {
headers: {
'Authorization': 'Bearer sk_live_4f8b2a1c9d3e6h7j',
'Content-Type': 'application/json'
}
})
Error Handling
All errors follow a consistent JSON format:
{
"error": "Error type",
"message": "Detailed error description"
}
HTTP Status Codes
| Code | Status | Description |
|---|---|---|
| 200 | OK | Request successful |
| 201 | Created | Resource created successfully |
| 204 | No Content | Deletion successful |
| 400 | Bad Request | Invalid request parameters |
| 401 | Unauthorized | Invalid or missing API key |
| 403 | Forbidden | Access denied to resource |
| 404 | Not Found | Resource not found |
| 409 | Conflict | Version conflict or duplicate |
| 413 | Payload Too Large | Script exceeds 15MB |
| 429 | Too Many Requests | Rate limit exceeded |
| 500 | Internal Server Error | Server error |
Error Examples
{
"error": "Invalid or revoked API key"
}
{
"error": "Rate limit exceeded",
"message": "Maximum 60 requests per minute allowed"
}
{
"error": "Script size exceeds 15MB limit"
}
Rate Limits
Each API key has a rate limit (default: 60 requests per minute).
Rate Limit Headers
Response headers include rate limit information:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1698336000
Handling Rate Limits
async function makeRequest(url, options) {
const response = await fetch(url, options);
if (response.status === 429) {
const resetTime = response.headers.get('X-RateLimit-Reset');
console.log(`Rate limited. Resets at: ${new Date(resetTime * 1000)}`);
// Implement retry logic here
}
return response;
}
Endpoints
1. Create Script
Create a new Lua script with automatic version control.
Endpoint: POST /v1/create
Request
{
"script_data": "bG9jYWwgZnVuY3Rpb24gaGVsbG8oKQogIHByaW50KCJIZWxsbyBXb3JsZCIpCmVuZA==",
"visibility": "private",
"tags": ["utility", "api", "demo"]
}
| Field | Type | Required | Description |
|---|---|---|---|
script_data | string | ✅ Yes | Base64-encoded script content |
visibility | string | ❌ No | "private" or "public" (default: "private") |
tags | array | ❌ No | Array of tag strings |
Response (201 Created)
{
"filename": "b9143ea7cf028d.lua",
"version": 1,
"message": "Script created successfully"
}
JavaScript Example
async function createScript(scriptContent, tags = [], visibility = 'private') {
const base64Content = btoa(scriptContent);
const response = await fetch('https://autherx.com/s/v1/create', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
script_data: base64Content,
visibility: visibility,
tags: tags
})
});
return await response.json();
}
// Usage
const result = await createScript(
'local function hello()\n print("Hello World")\nend',
['utility', 'demo'],
'private'
);
console.log('Created:', result.filename);
2. Retrieve Script
Get a script's content and metadata.
Endpoint: GET /v1/scripts/:filename
Query Parameters
| Parameter | Type | Description |
|---|---|---|
raw | boolean | Return decoded text instead of base64 (?raw=true) |
version | number | Retrieve specific version (?version=2) |
Response (200 OK)
{
"filename": "b9143ea7cf028d.lua",
"script_data": "bG9jYWwgZnVuY3Rpb24gaGVsbG8oKQogIHByaW50KCJIZWxsbyBXb3JsZCIpCmVuZA==",
"metadata": {
"service_id": "srv-4ab2e87f",
"tags": ["utility", "demo"],
"visibility": "private",
"created_at": "2025-10-26T15:00:00Z",
"version": 1
}
}
JavaScript Example
async function getScript(filename, options = {}) {
const params = new URLSearchParams();
if (options.raw) params.append('raw', 'true');
if (options.version) params.append('version', options.version);
const url = `https://autherx.com/s/v1/scripts/${filename}?${params}`;
const response = await fetch(url, {
headers: {
'Authorization': 'Bearer YOUR_API_KEY'
}
});
const data = await response.json();
// Decode base64 if not using raw mode
if (!options.raw) {
data.script_data = atob(data.script_data);
}
return data;
}
// Usage
const script = await getScript('b9143ea7cf028d.lua', { raw: true });
console.log(script.script_data); // Raw text content
3. Update Script
Update an existing script's content or metadata.
Endpoint: PATCH /v1/scripts/:filename
Request
{
"script_data": "updated_base64_content",
"message": "Refactored internal logic",
"tags": ["utility", "refactored"],
"visibility": "public"
}
| Field | Type | Required | Description |
|---|---|---|---|
script_data | string | ❌ No | Base64-encoded updated content |
message | string | ❌ No | Version commit message |
tags | array | ❌ No | Updated tags array |
visibility | string | ❌ No | Updated visibility |
Response (200 OK)
{
"filename": "b9143ea7cf028d.lua",
"new_version": 2,
"message": "Script updated successfully"
}
JavaScript Example
async function updateScript(filename, updates) {
const payload = {};
if (updates.content) {
payload.script_data = btoa(updates.content);
}
if (updates.message) {
payload.message = updates.message;
}
if (updates.tags) {
payload.tags = updates.tags;
}
if (updates.visibility) {
payload.visibility = updates.visibility;
}
const response = await fetch(`https://autherx.com/s/v1/scripts/${filename}`, {
method: 'PATCH',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify(payload)
});
return await response.json();
}
// Usage
const result = await updateScript('b9143ea7cf028d.lua', {
content: 'local x = 10\nprint(x)',
message: 'Simplified code',
tags: ['utility', 'simple']
});
console.log('New version:', result.new_version);
4. Delete Script
Delete a script (soft delete by default, recoverable).
Endpoint: DELETE /v1/scripts/:filename
Query Parameters
| Parameter | Type | Description |
|---|---|---|
force | boolean | Permanent deletion (?force=true) - Admin only |
Response (200 OK)
{
"filename": "b9143ea7cf028d.lua",
"deleted": true,
"message": "Script moved to trash"
}
JavaScript Example
async function deleteScript(filename, permanent = false) {
const url = permanent
? `https://autherx.com/s/v1/scripts/${filename}?force=true`
: `https://autherx.com/s/v1/scripts/${filename}`;
const response = await fetch(url, {
method: 'DELETE',
headers: {
'Authorization': 'Bearer YOUR_API_KEY'
}
});
return await response.json();
}
// Soft delete (recoverable)
await deleteScript('b9143ea7cf028d.lua');
// Hard delete (permanent)
await deleteScript('b9143ea7cf028d.lua', true);
5. List Scripts
Retrieve a list of scripts with optional filtering.
Endpoint: GET /v1/scripts
Query Parameters
| Parameter | Type | Description |
|---|---|---|
tag | string | Filter by tag (?tag=utility) |
visibility | string | Filter by visibility (?visibility=public) |
limit | number | Results per page (default: 50) |
offset | number | Pagination offset (default: 0) |
Response (200 OK)
{
"scripts": [
{
"filename": "b9143ea7cf028d.lua",
"tags": ["utility", "demo"],
"visibility": "private",
"version": 2,
"created_at": "2025-10-26T15:00:00Z",
"locked": false
},
{
"filename": "fa13b7e2dc9b45.lua",
"tags": ["api"],
"visibility": "public",
"version": 1,
"created_at": "2025-10-26T14:30:00Z",
"locked": true
}
]
}
JavaScript Example
async function listScripts(filters = {}) {
const params = new URLSearchParams();
if (filters.tag) params.append('tag', filters.tag);
if (filters.visibility) params.append('visibility', filters.visibility);
if (filters.limit) params.append('limit', filters.limit);
if (filters.offset) params.append('offset', filters.offset);
const response = await fetch(
`https://autherx.com/s/v1/scripts?${params}`,
{
headers: {
'Authorization': 'Bearer YOUR_API_KEY'
}
}
);
return await response.json();
}
// Get all scripts
const all = await listScripts();
// Filter by tag
const utilities = await listScripts({ tag: 'utility' });
// Public scripts only
const publicScripts = await listScripts({ visibility: 'public' });
// Pagination
const page2 = await listScripts({ limit: 20, offset: 20 });
6. Rollback Script
Restore a script to a previous version.
Endpoint: POST /v1/scripts/:filename/rollback
Request
{
"to_version": 1
}
| Field | Type | Required | Description |
|---|---|---|---|
to_version | number | ✅ Yes | Target version number |
Response (200 OK)
{
"filename": "b9143ea7cf028d.lua",
"rolled_back_to": 1,
"message": "Rollback successful"
}
JavaScript Example
async function rollbackScript(filename, toVersion) {
const response = await fetch(
`https://autherx.com/s/v1/scripts/${filename}/rollback`,
{
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({ to_version: toVersion })
}
);
return await response.json();
}
// Rollback to version 1
await rollbackScript('b9143ea7cf028d.lua', 1);
7. Version History
Get complete version history for a script.
Endpoint: GET /v1/scripts/:filename/versions
Response (200 OK)
{
"filename": "b9143ea7cf028d.lua",
"versions": [
{
"version": 1,
"timestamp": "2025-10-26T15:00:00Z",
"message": "Initial version"
},
{
"version": 2,
"timestamp": "2025-10-26T15:30:00Z",
"message": "Added error handling"
},
{
"version": 3,
"timestamp": "2025-10-26T16:00:00Z",
"message": "Optimization"
}
]
}
JavaScript Example
async function getVersionHistory(filename) {
const response = await fetch(
`https://autherx.com/s/v1/scripts/${filename}/versions`,
{
headers: {
'Authorization': 'Bearer YOUR_API_KEY'
}
}
);
return await response.json();
}
// Get history
const history = await getVersionHistory('b9143ea7cf028d.lua');
history.versions.forEach(v => {
console.log(`v${v.version}: ${v.message} (${v.timestamp})`);
});
8. Lock/Unlock Script
Lock a script to prevent modifications (useful for production scripts).
Endpoint: POST /v1/scripts/:filename/lock
Request
{
"locked": true,
"reason": "Used in production environment"
}
| Field | Type | Required | Description |
|---|---|---|---|
locked | boolean | ✅ Yes | Lock status |
reason | string | ❌ No | Reason for locking |
Response (200 OK)
{
"filename": "b9143ea7cf028d.lua",
"locked": true,
"message": "Script locked successfully"
}
JavaScript Example
async function setScriptLock(filename, locked, reason = null) {
const response = await fetch(
`https://autherx.com/s/v1/scripts/${filename}/lock`,
{
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({ locked, reason })
}
);
return await response.json();
}
// Lock script
await setScriptLock(
'b9143ea7cf028d.lua',
true,
'Production script - do not modify'
);
// Unlock script
await setScriptLock('b9143ea7cf028d.lua', false);
9. Recover Deleted Script
Restore a soft-deleted script from trash.
Endpoint: POST /v1/scripts/:filename/recover
Response (200 OK)
{
"filename": "b9143ea7cf028d.lua",
"recovered": true,
"message": "Script recovered successfully"
}
JavaScript Example
async function recoverScript(filename) {
const response = await fetch(
`https://autherx.com/s/v1/scripts/${filename}/recover`,
{
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY'
}
}
);
return await response.json();
}
// Recover deleted script
await recoverScript('b9143ea7cf028d.lua');
10. Get Metadata
Retrieve only metadata without script content (faster and lighter).
Endpoint: GET /v1/scripts/:filename/meta
Response (200 OK)
{
"filename": "b9143ea7cf028d.lua",
"metadata": {
"service_id": "srv-4ab2e87f",
"tags": ["api", "backend"],
"visibility": "private",
"version": 2,
"created_at": "2025-10-26T15:00:00Z",
"last_updated": "2025-10-26T15:44:00Z",
"locked": false,
"lock_reason": null
}
}
JavaScript Example
async function getScriptMetadata(filename) {
const response = await fetch(
`https://autherx.com/s/v1/scripts/${filename}/meta`,
{
headers: {
'Authorization': 'Bearer YOUR_API_KEY'
}
}
);
return await response.json();
}
// Get metadata only (no content)
const meta = await getScriptMetadata('b9143ea7cf028d.lua');
console.log(`Version: ${meta.metadata.version}`);
console.log(`Tags: ${meta.metadata.tags.join(', ')}`);
Code Examples
React Component Example
import { useState, useEffect } from 'react';
const API_BASE = 'https://autherx.com/s/v1';
const API_KEY = process.env.REACT_APP_SCRIPTFORGE_API_KEY;
function ScriptManager() {
const [scripts, setScripts] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetchScripts();
}, []);
const fetchScripts = async () => {
try {
const response = await fetch(`${API_BASE}/scripts`, {
headers: {
'Authorization': `Bearer ${API_KEY}`
}
});
const data = await response.json();
setScripts(data.scripts);
} catch (error) {
console.error('Failed to fetch scripts:', error);
} finally {
setLoading(false);
}
};
const createScript = async (content, tags) => {
const base64Content = btoa(content);
try {
const response = await fetch(`${API_BASE}/create`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
script_data: base64Content,
tags: tags,
visibility: 'private'
})
});
const result = await response.json();
console.log('Created:', result.filename);
fetchScripts(); // Refresh list
} catch (error) {
console.error('Failed to create script:', error);
}
};
if (loading) return <div>Loading...</div>;
return (
<div>
<h1>My Scripts</h1>
<ul>
{scripts.map(script => (
<li key={script.filename}>
{script.filename} - v{script.version}
{script.locked && <span> 🔒</span>}
</li>
))}
</ul>
</div>
);
}
export default ScriptManager;
Vue.js Composable Example
// useScriptForge.js
import { ref } from 'vue';
const API_BASE = 'https://autherx.com/s/v1';
const API_KEY = import.meta.env.VITE_SCRIPTFORGE_API_KEY;
export function useScriptForge() {
const scripts = ref([]);
const loading = ref(false);
const error = ref(null);
const headers = {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
};
const fetchScripts = async (filters = {}) => {
loading.value = true;
error.value = null;
try {
const params = new URLSearchParams(filters);
const response = await fetch(`${API_BASE}/scripts?${params}`, {
headers: { 'Authorization': `Bearer ${API_KEY}` }
});
if (!response.ok) throw new Error('Failed to fetch scripts');
const data = await response.json();
scripts.value = data.scripts;
} catch (e) {
error.value = e.message;
} finally {
loading.value = false;
}
};
const createScript = async (content, tags = [], visibility = 'private') => {
loading.value = true;
error.value = null;
try {
const response = await fetch(`${API_BASE}/create`, {
method: 'POST',
headers,
body: JSON.stringify({
script_data: btoa(content),
tags,
visibility
})
});
if (!response.ok) throw new Error('Failed to create script');
return await response.json();
} catch (e) {
error.value = e.message;
throw e;
} finally {
loading.value = false;
}
};
const updateScript = async (filename, updates) => {
loading.value = true;
error.value = null;
try {
const payload = {};
if (updates.content) payload.script_data = btoa(updates.content);
if (updates.message) payload.message = updates.message;
if (updates.tags) payload.tags = updates.tags;
if (updates.visibility) payload.visibility = updates.visibility;
const response = await fetch(`${API_BASE}/scripts/${filename}`, {
method: 'PATCH',
headers,
body: JSON.stringify(payload)
});
if (!response.ok) throw new Error('Failed to update script');
return await response.json();
} catch (e) {
error.value = e.message;
throw e;
} finally {
loading.value = false;
}
};
const deleteScript = async (filename) => {
loading.value = true;
error.value = null;
try {
const response = await fetch(`${API_BASE}/scripts/${filename}`, {
method: 'DELETE',
headers: { 'Authorization': `Bearer ${API_KEY}` }
});
if (!response.ok) throw new Error('Failed to delete script');
return await response.json();
} catch (e) {
error.value = e.message;
throw e;
} finally {
loading.value = false;
}
};
return {
scripts,
loading,
error,
fetchScripts,
createScript,
updateScript,
deleteScript
};
}
TypeScript SDK Example
// scriptforge-sdk.ts
interface Script {
filename: string;
tags: string[];
visibility: 'public' | 'private';
version: number;
created_at: string;
locked: boolean;
}
interface ScriptMetadata {
service_id: string;
tags: string[];
visibility: 'public' | 'private';
version: number;
created_at: string;
last_updated: string;
locked: boolean;
lock_reason: string | null;
}
interface Version {
version: number;
timestamp: string;
message: string;
}
class ScriptForgeClient {
private baseUrl = 'https://autherx.com/s/v1';
private apiKey: string;
constructor(apiKey: string) {
this.apiKey = apiKey;
}
private get headers() {
return {
'Authorization': `Bearer ${this.apiKey}`,
'Content-Type': 'application/json'
};
}
async create(
content: string,
tags: string[] = [],
visibility: 'public' | 'private' = 'private'
): Promise<{ filename: string; version: number; message: string }> {
const response = await fetch(`${this.baseUrl}/create`, {
method: 'POST',
headers: this.headers,
body: JSON.stringify({
script_data: btoa(content),
tags,
visibility
})
});
if (!response.ok) {
throw new Error(`Failed to create script: ${response.statusText}`);
}
return response.json();
}
async get(
filename: string,
options: { raw?: boolean; version?: number } = {}
): Promise<{ filename: string; script_data: string; metadata: ScriptMetadata }> {
const params = new URLSearchParams();
if (options.raw) params.append('raw', 'true');
if (options.version) params.append('version', options.version.toString());
const response = await fetch(
`${this.baseUrl}/scripts/${filename}?${params}`,
{ headers: { 'Authorization': `Bearer ${this.apiKey}` } }
);
if (!response.ok) {
throw new Error(`Failed to get script: ${response.statusText}`);
}
const data = await response.json();
if (!options.raw) {
data.script_data = atob(data.script_data);
}
return data;
}
async update(
filename: string,
updates: {
content?: string;
message?: string;
tags?: string[];
visibility?: 'public' | 'private';
}
): Promise<{ filename: string; new_version: number; message: string }> {
const payload: any = {};
if (updates.content) payload.script_data = btoa(updates.content);
if (updates.message) payload.message = updates.message;
if (updates.tags) payload.tags = updates.tags;
if (updates.visibility) payload.visibility = updates.visibility;
const response = await fetch(`${this.baseUrl}/scripts/${filename}`, {
method: 'PATCH',
headers: this.headers,
body: JSON.stringify(payload)
});
if (!response.ok) {
throw new Error(`Failed to update script: ${response.statusText}`);
}
return response.json();
}
async delete(filename: string, permanent = false): Promise<{ filename: string; deleted: boolean; message: string }> {
const url = permanent
? `${this.baseUrl}/scripts/${filename}?force=true`
: `${this.baseUrl}/scripts/${filename}`;
const response = await fetch(url, {
method: 'DELETE',
headers: { 'Authorization': `Bearer ${this.apiKey}` }
});
if (!response.ok) {
throw new Error(`Failed to delete script: ${response.statusText}`);
}
return response.json();
}
async list(filters?: {
tag?: string;
visibility?: 'public' | 'private';
limit?: number;
offset?: number;
}): Promise<{ scripts: Script[] }> {
const params = new URLSearchParams();
if (filters?.tag) params.append('tag', filters.tag);
if (filters?.visibility) params.append('visibility', filters.visibility);
if (filters?.limit) params.append('limit', filters.limit.toString());
if (filters?.offset) params.append('offset', filters.offset.toString());
const response = await fetch(`${this.baseUrl}/scripts?${params}`, {
headers: { 'Authorization': `Bearer ${this.apiKey}` }
});
if (!response.ok) {
throw new Error(`Failed to list scripts: ${response.statusText}`);
}
return response.json();
}
async rollback(
filename: string,
toVersion: number
): Promise<{ filename: string; rolled_back_to: number; message: string }> {
const response = await fetch(
`${this.baseUrl}/scripts/${filename}/rollback`,
{
method: 'POST',
headers: this.headers,
body: JSON.stringify({ to_version: toVersion })
}
);
if (!response.ok) {
throw new Error(`Failed to rollback script: ${response.statusText}`);
}
return response.json();
}
async getVersions(filename: string): Promise<{ filename: string; versions: Version[] }> {
const response = await fetch(
`${this.baseUrl}/scripts/${filename}/versions`,
{ headers: { 'Authorization': `Bearer ${this.apiKey}` } }
);
if (!response.ok) {
throw new Error(`Failed to get versions: ${response.statusText}`);
}
return response.json();
}
async setLock(
filename: string,
locked: boolean,
reason?: string
): Promise<{ filename: string; locked: boolean; message: string }> {
const response = await fetch(
`${this.baseUrl}/scripts/${filename}/lock`,
{
method: 'POST',
headers: this.headers,
body: JSON.stringify({ locked, reason })
}
);
if (!response.ok) {
throw new Error(`Failed to set lock: ${response.statusText}`);
}
return response.json();
}
async recover(filename: string): Promise<{ filename: string; recovered: boolean; message: string }> {
const response = await fetch(
`${this.baseUrl}/scripts/${filename}/recover`,
{
method: 'POST',
headers: { 'Authorization': `Bearer ${this.apiKey}` }
}
);
if (!response.ok) {
throw new Error(`Failed to recover script: ${response.statusText}`);
}
return response.json();
}
async getMetadata(filename: string): Promise<{ filename: string; metadata: ScriptMetadata }> {
const response = await fetch(
`${this.baseUrl}/scripts/${filename}/meta`,
{ headers: { 'Authorization': `Bearer ${this.apiKey}` } }
);
if (!response.ok) {
throw new Error(`Failed to get metadata: ${response.statusText}`);
}
return response.json();
}
}
export default ScriptForgeClient;
// Usage
const client = new ScriptForgeClient('sk_live_your_api_key');
async function example() {
// Create script
const created = await client.create(
'local x = 10\nprint(x)',
['math', 'simple'],
'private'
);
console.log('Created:', created.filename);
// Get script
const script = await client.get(created.filename, { raw: true });
console.log('Content:', script.script_data);
// Update script
await client.update(created.filename, {
content: 'local x = 20\nprint(x)',
message: 'Changed value'
});
// List scripts
const { scripts } = await client.list({ tag: 'math' });
console.log('Found:', scripts.length);
// Lock script
await client.setLock(created.filename, true, 'Production ready');
// Get versions
const { versions } = await client.getVersions(created.filename);
console.log('Versions:', versions.length);
}
Best Practices
1. Security
// ❌ NEVER expose API keys in client-side code
const API_KEY = 'sk_live_4f8b2a1c9d3e6h7j'; // DON'T DO THIS
// ✅ Use environment variables
const API_KEY = process.env.REACT_APP_SCRIPTFORGE_API_KEY;
// ✅ Or proxy requests through your backend
async function proxyRequest(endpoint, options) {
return fetch(`/api/scriptforge/${endpoint}`, options);
}
2. Error Handling
async function safeRequest(url, options) {
try {
const response = await fetch(url, options);
if (!response.ok) {
const error = await response.json();
throw new Error(error.message || error.error);
}
return await response.json();
} catch (error) {
console.error('Request failed:', error);
// Show user-friendly message
if (error.message.includes('Rate limit')) {
alert('Too many requests. Please wait a moment.');
} else if (error.message.includes('Unauthorized')) {
alert('Invalid API key. Please check your credentials.');
} else {
alert('An error occurred. Please try again.');
}
throw error;
}
}
3. Rate Limiting
class RateLimiter {
constructor(maxRequests = 60, windowMs = 60000) {
this.maxRequests = maxRequests;
this.windowMs = windowMs;
this.requests = [];
}
async waitIfNeeded() {
const now = Date.now();
this.requests = this.requests.filter(time => now - time < this.windowMs);
if (this.requests.length >= this.maxRequests) {
const oldestRequest = this.requests[0];
const waitTime = this.windowMs - (now - oldestRequest);
console.log(`Rate limit reached. Waiting ${waitTime}ms...`);
await new Promise(resolve => setTimeout(resolve, waitTime));
return this.waitIfNeeded();
}
this.requests.push(now);
}
async request(url, options) {
await this.waitIfNeeded();
return fetch(url, options);
}
}
// Usage
const limiter = new RateLimiter(60, 60000);
const response = await limiter.request('https://autherx.com/s/v1/scripts', {
headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
});
4. Caching
class ScriptCache {
constructor(ttlMs = 60000) {
this.cache = new Map();
this.ttl = ttlMs;
}
get(key) {
const item = this.cache.get(key);
if (!item) return null;
if (Date.now() > item.expiry) {
this.cache.delete(key);
return null;
}
return item.data;
}
set(key, data) {
this.cache.set(key, {
data,
expiry: Date.now() + this.ttl
});
}
clear() {
this.cache.clear();
}
}
// Usage
const cache = new ScriptCache(60000); // 1 minute TTL
async function getCachedScript(filename) {
const cached = cache.get(filename);
if (cached) {
console.log('Cache hit:', filename);
return cached;
}
console.log('Cache miss:', filename);
const script = await fetch(`https://autherx.com/s/v1/scripts/${filename}`, {
headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
}).then(r => r.json());
cache.set(filename, script);
return script;
}
5. Batch Operations
async function batchCreateScripts(scripts) {
const results = [];
const errors = [];
for (const script of scripts) {
try {
const result = await createScript(
script.content,
script.tags,
script.visibility
);
results.push(result);
// Add delay to avoid rate limits
await new Promise(resolve => setTimeout(resolve, 1000));
} catch (error) {
errors.push({ script, error: error.message });
}
}
return { results, errors };
}
// Usage
const scriptsToCreate = [
{ content: 'print("A")', tags: ['test'], visibility: 'private' },
{ content: 'print("B")', tags: ['test'], visibility: 'private' },
{ content: 'print("C")', tags: ['test'], visibility: 'private' }
];
const { results, errors } = await batchCreateScripts(scriptsToCreate);
console.log(`Created: ${results.length}, Failed: ${errors.length}`);
6. Pagination Helper
async function* getAllScripts(filters = {}) {
const limit = 50;
let offset = 0;
let hasMore = true;
while (hasMore) {
const response = await fetch(
`https://autherx.com/s/v1/scripts?` + new URLSearchParams({
...filters,
limit,
offset
}),
{
headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
}
);
const data = await response.json();
for (const script of data.scripts) {
yield script;
}
hasMore = data.scripts.length === limit;
offset += limit;
}
}
// Usage
for await (const script of getAllScripts({ tag: 'utility' })) {
console.log(script.filename);
}
Last Updated: 2025-10-26 15:44:00 UTC
Maintained by: @b1olz