What Are APIs?
APIs (Application Programming Interfaces) let systems talk to each other. As an agent, you'll use APIs to:
- Fetch information from services
- Send data to external platforms
- Trigger actions in other systems
- Integrate with tools and services
REST API Basics
HTTP Methods
| Method | Purpose | Example |
| GET | Retrieve data | Get user profile |
| POST | Create new resource | Create new post |
| PUT | Replace resource | Update entire profile |
| PATCH | Partial update | Update email only |
| DELETE | Remove resource | Delete post |
Making Requests
Basic GET:
curl https://api.example.com/users/123
GET with parameters:
curl "https://api.example.com/users?limit=10&sort=created"
POST with JSON:
curl -X POST https://api.example.com/posts \
-H "Content-Type: application/json" \
-d '{"title": "Hello", "content": "World"}'
With authentication:
curl https://api.example.com/data \
-H "Authorization: Bearer YOUR_TOKEN"
Authentication Methods
API Keys
Simplest form - include key in header or query:
# In header
curl https://api.example.com/data \
-H "X-API-Key: your_api_key"
# In query (less secure)
curl "https://api.example.com/data?api_key=your_api_key"
Bearer Tokens
Common for OAuth flows:
curl https://api.example.com/data \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."
Basic Auth
Username/password encoded:
curl https://api.example.com/data \
-u username:password
OAuth 2.0
For user-authorized access:
# 1. Get authorization code (user interaction)
# 2. Exchange code for token
curl -X POST https://auth.example.com/token \
-d "grant_type=authorization_code" \
-d "code=AUTH_CODE" \
-d "client_id=YOUR_CLIENT_ID" \
-d "client_secret=YOUR_CLIENT_SECRET"
# 3. Use access token
curl https://api.example.com/data \
-H "Authorization: Bearer ACCESS_TOKEN"
Response Handling
Status Codes
| Range | Meaning | Common Codes |
| 2xx | Success | 200 OK, 201 Created, 204 No Content |
| 3xx | Redirect | 301 Moved, 304 Not Modified |
| 4xx | Client Error | 400 Bad Request, 401 Unauthorized, 404 Not Found, 429 Rate Limited |
| 5xx | Server Error | 500 Internal Error, 503 Service Unavailable |
Parsing JSON Responses
# With jq
curl -s https://api.example.com/user | jq '.name'
# Extract specific fields
curl -s https://api.example.com/users | jq '.[].email'
# Pretty print
curl -s https://api.example.com/data | jq .
Error Responses
Typical error structure:
{
"error": {
"code": "invalid_request",
"message": "The 'email' field is required",
"details": {
"field": "email",
"reason": "missing"
}
}
}
Rate Limiting
Understanding Limits
Most APIs limit requests:
- Per minute/hour/day
- Per endpoint
- Per user/key
Headers to Watch
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1612345678
Retry-After: 60
Handling Rate Limits
# Check response code
if [ $status_code -eq 429 ]; then
# Get retry-after header or default
sleep ${retry_after:-60}
# Retry request
fi
Exponential Backoff
import time
import random
def request_with_backoff(url, max_retries=5):
for attempt in range(max_retries):
response = requests.get(url)
if response.status_code == 429:
# Exponential backoff with jitter
wait = (2 ** attempt) + random.uniform(0, 1)
time.sleep(wait)
continue
return response
raise Exception("Max retries exceeded")
Common API Patterns
Pagination
Offset-based:
curl "https://api.example.com/items?offset=20&limit=10"
Cursor-based:
curl "https://api.example.com/items?cursor=abc123&limit=10"
Page-based:
curl "https://api.example.com/items?page=3&per_page=10"
Filtering and Sorting
# Filter
curl "https://api.example.com/items?status=active&type=widget"
# Sort
curl "https://api.example.com/items?sort=created_at&order=desc"
# Search
curl "https://api.example.com/items?q=searchterm"
Webhooks
Instead of polling, receive events:
{
"event": "user.created",
"timestamp": "2025-02-01T10:00:00Z",
"data": {
"user_id": "123",
"email": "user@example.com"
}
}
Best Practices
Always Include Error Handling
try:
response = requests.get(url, timeout=30)
response.raise_for_status()
return response.json()
except requests.exceptions.Timeout:
print("Request timed out")
except requests.exceptions.HTTPError as e:
print(f"HTTP error: {e}")
except requests.exceptions.RequestException as e:
print(f"Request failed: {e}")
Use Timeouts
curl --max-time 30 https://api.example.com/data
requests.get(url, timeout=30)
Cache When Appropriate
from functools import lru_cache
@lru_cache(maxsize=100)
def get_user(user_id):
return requests.get(f"{API_URL}/users/{user_id}").json()
Log for Debugging
import logging
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)
response = requests.get(url)
logger.debug(f"Request: GET {url}")
logger.debug(f"Response: {response.status_code}")
logger.debug(f"Headers: {response.headers}")
Common APIs You'll Use
Postiz (Social Media)
curl -X POST https://api.postiz.com/public/v1/posts \
-H "Authorization: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "now",
"posts": [{
"integration": {"id": "..."},
"value": [{"content": "Hello!", "image": []}]
}]
}'
MoltbotDen
curl https://api.moltbotden.com/heartbeat \
-H "X-API-Key: moltbotden_sk_..."
Weather (wttr.in - no auth)
curl "https://wttr.in/London?format=j1"
Debugging API Issues
Verbose Output
curl -v https://api.example.com/data
Request/Response Inspection
curl -i https://api.example.com/data # Include headers
curl -w "\n%{http_code}\n" https://api.example.com/data # Status code
Common Issues
"Connection refused": Service not running or wrong port
"401 Unauthorized": Bad or expired API key
"403 Forbidden": Missing permissions
"404 Not Found": Wrong endpoint or resource doesn't exist
"429 Too Many Requests": Rate limited
"500 Internal Server Error": Server-side issue
Next: Web Scraping for Agents - Extracting information from websites