401 Unauthorized
Problem: Authentication failing Quick Fix: Verify API key format, environment variables, and test authentication.1
1. Verify API Key Format
Check that your API key is properly formatted:
- JavaScript
- Python
- HTTPie
Copy
// Check API key format
if (!API_KEY || API_KEY.length < 20) {
throw new Error('Invalid API key format');
}
// Ensure Bearer prefix in header
const headers = {
'Authorization': `Bearer ${API_KEY}`, // Must include "Bearer "
'Content-Type': 'application/json'
};
Copy
# Check API key format
if not API_KEY or len(API_KEY) < 20:
raise ValueError("Invalid API key format")
# Ensure Bearer prefix in header
headers = {
"Authorization": f"Bearer {API_KEY}", # Must include "Bearer "
"Content-Type": "application/json"
}
Copy
# Verify API key is set
if [ -z "$AGI_API_KEY" ]; then
echo "Error: AGI_API_KEY not set"
exit 1
fi
# Test authentication
http GET https://api.agi.tech/v1/models \
Authorization:"Bearer $AGI_API_KEY"
2
2. Check Environment Variables
Load API key from environment, never hardcode:
- JavaScript
- Python
- HTTPie
Copy
// Load from environment
const API_KEY = process.env.AGI_API_KEY;
if (!API_KEY) {
throw new Error('AGI_API_KEY environment variable not set');
}
// For development, use .env file with dotenv
import 'dotenv/config';
const API_KEY = process.env.AGI_API_KEY;
Copy
import os
# Load from environment
API_KEY = os.getenv("AGI_API_KEY")
if not API_KEY:
raise ValueError("AGI_API_KEY environment variable not set")
# For development, use .env file
from dotenv import load_dotenv
load_dotenv()
API_KEY = os.getenv("AGI_API_KEY")
Copy
# Set in environment
export AGI_API_KEY="your_api_key_here"
# Or use .env file (requires httpie-dotenv plugin)
# http --env-file=.env GET https://api.agi.tech/v1/models
3
3. Test Authentication
Verify your API key works before starting work:
- JavaScript
- Python
- HTTPie
Copy
async function testAuth() {
try {
const response = await fetch('https://api.agi.tech/v1/models', {
headers: { 'Authorization': `Bearer ${API_KEY}` }
});
if (response.status === 200) {
console.log('✓ Authentication successful');
return true;
} else if (response.status === 401) {
console.log('✗ Invalid API key');
return false;
} else if (response.status === 403) {
console.log('✗ API key not authorized for this resource');
return false;
}
} catch (e) {
console.log(`✗ Connection error: ${e.message}`);
return false;
}
}
// Run before starting work
if (!(await testAuth())) {
process.exit(1);
}
Copy
def test_auth():
"""Test if API key is valid"""
try:
response = requests.get(
f"{BASE_URL}/models",
headers={"Authorization": f"Bearer {API_KEY}"}
)
if response.status_code == 200:
print("✓ Authentication successful")
return True
elif response.status_code == 401:
print("✗ Invalid API key")
return False
elif response.status_code == 403:
print("✗ API key not authorized for this resource")
return False
except Exception as e:
print(f"✗ Connection error: {e}")
return False
# Run before starting work
if not test_auth():
raise SystemExit("Authentication failed")
Copy
# Test authentication
RESPONSE=$(http GET https://api.agi.tech/v1/models \
Authorization:"Bearer $AGI_API_KEY" 2>&1)
if echo "$RESPONSE" | grep -q "401"; then
echo "✗ Invalid API key"
exit 1
elif echo "$RESPONSE" | grep -q "403"; then
echo "✗ API key not authorized"
exit 1
else
echo "✓ Authentication successful"
fi
Authentication Not Preserved
Problem: Authentication state is lost when restoring from snapshot Solution: Use filesystem snapshots and verify default environmentCheck Snapshot Mode
Check Snapshot Mode
Ensure you’re using
filesystem mode, not memory:- JavaScript
- Python
- HTTPie
Copy
// Correct: Use filesystem for authentication
await fetch(`https://api.agi.tech/v1/sessions/${sessionId}?save_snapshot_mode=filesystem&save_as_default=true`, {
method: 'DELETE',
headers: { 'Authorization': `Bearer ${API_KEY}` }
});
Copy
# Correct: Use filesystem for authentication
requests.delete(
f"{BASE_URL}/sessions/{session_id}",
headers=HEADERS,
params={
"save_snapshot_mode": "filesystem", # Not "memory" or "none"
"save_as_default": "true"
}
)
Copy
# Correct: Use filesystem for authentication
http DELETE "https://api.agi.tech/v1/sessions/$SESSION_ID?save_snapshot_mode=filesystem&save_as_default=true" \
Authorization:"Bearer $AGI_API_KEY"
Verify Default Environment
Verify Default Environment
Check if default environment is set correctly:
- JavaScript
- Python
- HTTPie
Copy
// When creating session, ensure you're restoring from default
const response = await fetch('https://api.agi.tech/v1/sessions', {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
agent_name: 'agi-0',
restore_default_environment_from_user_id: userId // Must match
})
});
Copy
# When creating session, ensure you're restoring from default
response = requests.post(
f"{BASE_URL}/sessions",
headers=HEADERS,
json={
"agent_name": "agi-0",
"restore_default_environment_from_user_id": user_id # Must match
}
)
Copy
# When creating session, ensure you're restoring from default
http POST https://api.agi.tech/v1/sessions \
Authorization:"Bearer $AGI_API_KEY" \
agent_name=agi-0 \
restore_default_environment_from_user_id=$USER_ID
Token Expiration
Token Expiration
Some authentication tokens expire. You may need to re-authenticate:
- JavaScript
- Python
- HTTPie
Copy
// Check if authentication is still valid
const result = await session.runTask("Check if I'm logged in");
if (result.toLowerCase().includes("not logged in")) {
// Re-authenticate and save new snapshot
await session.runTask("Login again");
// Save updated snapshot
await fetch(`https://api.agi.tech/v1/sessions/${sessionId}?save_snapshot_mode=filesystem&save_as_default=true`, {
method: 'DELETE',
headers: { 'Authorization': `Bearer ${API_KEY}` }
});
}
Copy
# Check if authentication is still valid
result = session.run_task("Check if I'm logged in")
if "not logged in" in result.lower():
# Re-authenticate and save new snapshot
session.run_task("Login again")
# Save updated snapshot
requests.delete(
f"{BASE_URL}/sessions/{session_id}",
headers=HEADERS,
params={
"save_snapshot_mode": "filesystem",
"save_as_default": "true"
}
)
Copy
# Check authentication status
RESULT=$(http POST https://api.agi.tech/v1/sessions/$SESSION_ID/message \
Authorization:"Bearer $AGI_API_KEY" \
message="Check if I'm logged in" | jq -r '.content')
if echo "$RESULT" | grep -qi "not logged in"; then
# Re-authenticate
http POST https://api.agi.tech/v1/sessions/$SESSION_ID/message \
Authorization:"Bearer $AGI_API_KEY" \
message="Login again"
# Save updated snapshot
http DELETE "https://api.agi.tech/v1/sessions/$SESSION_ID?save_snapshot_mode=filesystem&save_as_default=true" \
Authorization:"Bearer $AGI_API_KEY"
fi
Snapshot Restoration Fails
Problem: Unable to restore from snapshot Solution: Implement fallback logic with multiple restore strategies- JavaScript
- Python
- HTTPie
Copy
async function safeRestoreFromSnapshot(sourceSessionId, userId) {
try {
// Try restoring from specific session
const response = await fetch('https://api.agi.tech/v1/sessions', {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
agent_name: 'agi-0',
restore_from_session_id: sourceSessionId
})
});
if (response.ok) {
return (await response.json()).session_id;
}
if (response.status === 404) {
// Snapshot not found, try default
console.log('Specific snapshot not found, trying default...');
const defaultResponse = await fetch('https://api.agi.tech/v1/sessions', {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
agent_name: 'agi-0',
restore_default_environment_from_user_id: userId
})
});
return (await defaultResponse.json()).session_id;
}
} catch (e) {
// Fallback to fresh session
console.log('Restoration failed, creating fresh session...');
const freshResponse = await fetch('https://api.agi.tech/v1/sessions', {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ agent_name: 'agi-0' })
});
return (await freshResponse.json()).session_id;
}
}
Copy
def safe_restore_from_snapshot(source_session_id, user_id):
try:
# Try restoring from specific session
response = requests.post(
f"{BASE_URL}/sessions",
headers=HEADERS,
json={
"agent_name": "agi-0",
"restore_from_session_id": source_session_id
}
)
return response.json()["session_id"]
except requests.HTTPError as e:
if e.response.status_code == 404:
# Snapshot not found, try default
print("Specific snapshot not found, trying default...")
response = requests.post(
f"{BASE_URL}/sessions",
headers=HEADERS,
json={
"agent_name": "agi-0",
"restore_default_environment_from_user_id": user_id
}
)
return response.json()["session_id"]
else:
# Fallback to fresh session
print("Restoration failed, creating fresh session...")
response = requests.post(
f"{BASE_URL}/sessions",
headers=HEADERS,
json={"agent_name": "agi-0"}
)
return response.json()["session_id"]
Copy
# Try restoring from specific session
SESSION=$(http POST https://api.agi.tech/v1/sessions \
Authorization:"Bearer $AGI_API_KEY" \
agent_name=agi-0 \
restore_from_session_id=$SOURCE_SESSION_ID 2>/dev/null | jq -r '.session_id')
# If failed, try default
if [ -z "$SESSION" ] || [ "$SESSION" = "null" ]; then
echo "Specific snapshot not found, trying default..."
SESSION=$(http POST https://api.agi.tech/v1/sessions \
Authorization:"Bearer $AGI_API_KEY" \
agent_name=agi-0 \
restore_default_environment_from_user_id=$USER_ID | jq -r '.session_id')
fi
# If still failed, create fresh
if [ -z "$SESSION" ] || [ "$SESSION" = "null" ]; then
echo "Restoration failed, creating fresh session..."
SESSION=$(http POST https://api.agi.tech/v1/sessions \
Authorization:"Bearer $AGI_API_KEY" \
agent_name=agi-0 | jq -r '.session_id')
fi