The AI SEO Agents API is a REST API hosted at https://api.aiagentssee.com/v1/. All endpoints require authentication via Cognito JWT or API key, following industry standards outlined in the OAuth 2.0 Authorization Framework (RFC 6749). Responses are JSON-encoded. The API design follows principles from the Google API Design Guide, including resource-oriented URLs and standard HTTP methods. For a complete platform overview before diving into the API, see the Quick Start Guide. The API currently processes thousands of requests daily across hundreds of managed sites, with 99.9% uptime over the past 12 months.

Authentication
The API supports two authentication methods. Include one of the following headers with every request:
| Method | Header | Format |
|---|---|---|
| Cognito JWT | Authorization | Bearer <id_token> |
| API Key | X-API-Key | sak_<key_string> |
API keys can be created and managed in Settings → API Keys. Each key is hashed with SHA-256 before storage — the raw key is shown only once at creation time.
Choosing an Authentication Method
The right authentication method depends on your integration type and security requirements. Based on patterns from over 500 API integrations across our customer base, here is how the two methods compare:
| Factor | Cognito JWT | API Key |
|---|---|---|
| Best for | Browser-based dashboards, SPAs, interactive apps | Server-to-server integrations, CI/CD pipelines, scripts |
| Token lifetime | 1 hour (auto-refreshed via refresh token) | No expiration (revoke manually) |
| Security model | Short-lived, rotates automatically, supports MFA | Long-lived, must be stored securely as environment variable |
| Setup complexity | Requires Cognito auth flow (login UI) | Single header — copy key and use immediately |
| Rate limit scope | Per-user (tied to Cognito sub) | Per-key (tied to key hash) |
For most production integrations, we recommend starting with API keys for simplicity, then migrating to JWT if you need per-user access control or MFA enforcement. Agencies managing client sites typically use one API key per client site for clean separation of rate limits and audit trails.
Base URL
https://api.aiagentssee.com/v1/dashboardSEO Agents API Endpoints
Agents
| Method | Path | Description |
|---|---|---|
| GET | /agents | List all agents. Optional: ?status=active|paused |
| POST | /agents | Create a new agent (name, keywords, tone, word_target) |
| GET | /agents/{id} | Get a single agent by ID |
| PUT | /agents/{id} | Update agent fields (name, keywords, tone, status) |
| DELETE | /agents/{id} | Soft-delete an agent (sets status to "deleted") |
Jobs
| Method | Path | Description |
|---|---|---|
| POST | /jobs | Trigger a new job (create, enhance, optimize, publish) |
| GET | /jobs | List jobs. Optional: ?agent_id=&status= |
| GET | /jobs/{id}/progress | Get live progress events. Optional: ?since=timestamp |
Articles
| Method | Path | Description |
|---|---|---|
| GET | /articles | List S3 articles with word counts and SEO scores |
| GET | /preview?s3_key=... | HTML preview of an S3 article |
Sites
| Method | Path | Description |
|---|---|---|
| POST | /sites | Register a new WordPress site |
| GET | /sites | List connected sites |
| PUT | /sites/{id} | Update site configuration |
| DELETE | /sites/{id} | Remove a connected site |
| POST | /sites/{id}/verify | Test site connectivity |
Other
| Method | Path | Description |
|---|---|---|
| GET | /stats | Dashboard statistics (active agents, total articles, avg score) |
| GET | /chart-data | Chart data for activity and category visualizations |
| GET | /health | Health check (no auth required). Returns 200 OK. |
Creating a Job — Example
curl -X POST https://api.aiagentssee.com/v1/dashboard/jobs \
-H "Authorization: Bearer <id_token>" \
-H "Content-Type: application/json" \
-d '{
"agent_id": "agent-a1b2c3d4",
"job_type": "create",
"keyword": "best trade show booths 2026"
}'Response:
{
"job_id": "content-a1b2c3d4",
"status": "pending",
"keyword": "best trade show booths 2026",
"agent_id": "agent-a1b2c3d4",
"created_at": "2026-02-26T10:30:00Z"
}Rate Limits
| Plan | Requests/Minute | Concurrent Jobs |
|---|---|---|
| Starter | 60 | 2 |
| Professional | 120 | 5 |
| Agency | 300 | 15 |
| Enterprise | Custom | Custom |
Rate-limited requests return 429 Too Many Requests with a Retry-After header. Implement exponential backoff in your client.
Rate Limit Best Practices
Production integrations that process hundreds of articles per month need a robust rate limiting strategy. Based on our experience supporting high-volume agency deployments, these patterns prevent disruptions:
- Exponential backoff with jitter — When you receive a 429 response, wait for the
Retry-Afterheader value, then add random jitter (0-500ms) to prevent thundering herd problems when multiple clients retry simultaneously. - Request queuing — For batch operations (e.g., publishing 20 articles), queue requests and process them at 80% of your plan's rate limit. This leaves headroom for interactive dashboard requests.
- Circuit breaker pattern — After 3 consecutive 429 responses, pause all requests for 30 seconds before resuming. This prevents wasting API calls during rate limit windows.
import time
import random
def api_request_with_backoff(url, headers, max_retries=5):
"""Exponential backoff with jitter for rate-limited APIs."""
for attempt in range(max_retries):
response = requests.get(url, headers=headers)
if response.status_code != 429:
return response
retry_after = int(response.headers.get('Retry-After', 2 ** attempt))
jitter = random.uniform(0, 0.5)
time.sleep(retry_after + jitter)
raise Exception("Max retries exceeded")Error Handling
The API uses standard HTTP status codes to indicate the success or failure of requests. Error responses include a JSON body with a message field describing the problem and, where applicable, a code field with a machine-readable error identifier. Your client application should handle these error categories gracefully to provide a reliable integration.
| Status Code | Meaning | Common Causes | Recommended Action |
|---|---|---|---|
| 400 | Bad Request | Missing required fields, invalid JSON, invalid parameter values | Check request body against the endpoint schema. Validate inputs before sending. |
| 401 | Unauthorized | Missing or expired JWT token, invalid API key | Refresh the JWT token or verify the API key is correct and active. |
| 403 | Forbidden | Valid authentication but insufficient permissions for the requested resource | Check that the authenticated user owns the requested agent, job, or site. |
| 404 | Not Found | Invalid endpoint path, non-existent resource ID | Verify the URL and resource ID. Check that the resource has not been deleted. |
| 409 | Conflict | Duplicate resource creation, status transition conflict | The operation conflicts with the current resource state. Read the resource and retry. |
| 429 | Too Many Requests | Rate limit exceeded | Wait for the duration specified in the Retry-After header before retrying. |
| 500 | Internal Server Error | Unexpected server-side error | Retry with exponential backoff. If persistent, contact support. |
// Example error response
{
"message": "Agent not found: agent-xyz12345",
"code": "RESOURCE_NOT_FOUND",
"request_id": "req-a1b2c3d4-5678-90ab-cdef"
}Always log the request_id from error responses. When contacting support, include this ID to help us quickly locate the specific request in our logs and diagnose the issue.
Common Error Scenarios
These are the most frequently encountered error patterns based on analysis of support tickets from our customer base. Each scenario includes the root cause and recommended fix:
| Scenario | Error | Root Cause | Fix |
|---|---|---|---|
| Job creation fails for new agent | 400 Bad Request | Agent has no keywords configured — the keywords array is empty | Add at least one keyword via PUT /agents/{id} before triggering jobs |
| Publish job stalls at "processing" | 409 Conflict | Previous job for the same agent is still running — concurrent job limit reached | Wait for the active job to complete, or increase your plan's concurrent job limit |
| Article preview returns empty | 404 Not Found | The s3_key references a deleted or expired article (90-day lifecycle) | Re-generate the article with a new create job |
| Webhook never fires after publish | — | Webhook endpoint returned non-2xx during verification or the event type is not subscribed | Check webhook health in Settings → Webhooks and verify the event subscription list |
| JWT token rejected after working | 401 Unauthorized | Token expired (1-hour lifetime) and the client is not refreshing automatically | Implement token refresh using the Cognito refresh token flow before each API call |
Pagination
List endpoints that return multiple items support cursor-based pagination. This is more efficient than offset-based pagination for large datasets because it avoids the performance degradation that occurs when skipping many records. Pagination parameters are passed as query string parameters and pagination metadata is returned in the response body.
| Parameter | Type | Default | Description |
|---|---|---|---|
| limit | integer | 25 | Maximum number of items to return per page (max: 100) |
| cursor | string | null | Opaque cursor from the previous response to fetch the next page |
| sort | string | created_at:desc | Sort field and direction (e.g., created_at:asc, score:desc) |
# First page
curl "https://api.aiagentssee.com/v1/dashboard/articles?limit=10" \
-H "Authorization: Bearer <id_token>"
# Next page (using cursor from previous response)
curl "https://api.aiagentssee.com/v1/dashboard/articles?limit=10&cursor=eyJzayI6IjIwMjYtMDItMjUifQ" \
-H "Authorization: Bearer <id_token>"The response includes a next_cursor field when more results are available. When next_cursor is null, you have reached the end of the result set. Cursors are opaque strings that encode the position in the dataset — do not attempt to decode or construct them manually.
Webhook Callbacks
Instead of polling the API for job status updates, you can configure webhook callbacks to receive push notifications when events occur. Webhooks are the recommended approach for production integrations because they reduce API calls, provide lower latency, and eliminate the complexity of managing polling loops. See the dedicated Webhook Setup guide for complete configuration instructions.
- Job completion: Triggered when a content, publish, or audit job reaches a terminal state (completed or failed). The payload includes the job ID, final status, result summary, and the S3 key for generated artifacts.
- Article published: Triggered when an article is successfully published to WordPress. The payload includes the WordPress post ID, URL, publish status, and the SEO score at time of publication.
- Rank alert: Triggered when a keyword ranking change exceeds your configured threshold. The payload includes the keyword, old position, new position, and the page URL that ranks.
- Audit complete: Triggered when a site-wide audit finishes. The payload includes the overall site score, number of issues found by severity, and a presigned URL for the full report.
SEO Agents API Code Examples
The following examples demonstrate the most common API operations. All examples use curl for clarity, but the API works with any HTTP client. Replace <id_token> with your Cognito JWT or use -H "X-API-Key: sak_your_key" for API key authentication.
Create an Agent
curl -X POST https://api.aiagentssee.com/v1/dashboard/agents \
-H "Authorization: Bearer <id_token>" \
-H "Content-Type: application/json" \
-d '{
"name": "Trade Show Content Agent",
"keywords": ["trade show booth cost", "custom trade show booth"],
"tone": "professional",
"word_target": 2500,
"schedule": "weekly"
}'List Articles with Filtering
# List articles for a specific agent, sorted by SEO score
curl "https://api.aiagentssee.com/v1/dashboard/articles?agent_id=agent-a1b2c3d4&sort=score:desc&limit=20" \
-H "X-API-Key: sak_your_api_key"Poll Job Progress
# Get progress events since a specific timestamp
curl "https://api.aiagentssee.com/v1/dashboard/jobs/content-a1b2c3d4/progress?since=2026-02-26T10:30:00Z" \
-H "Authorization: Bearer <id_token>"Trigger a Publish Job
curl -X POST https://api.aiagentssee.com/v1/dashboard/jobs \
-H "Authorization: Bearer <id_token>" \
-H "Content-Type: application/json" \
-d '{
"agent_id": "agent-a1b2c3d4",
"job_type": "publish",
"s3_key": "articles/agent-a1b2c3d4/trade-show-booth-cost.md",
"publish_action": "elementor_publish",
"status_on_publish": "draft"
}'For WebSocket-based real-time progress tracking (recommended for interactive applications), connect to wss://ws.aiagentssee.com/v1?token=<id_token> and send a subscribe message with the job ID. See the workflow documentation for details on the WebSocket protocol and event format.
CORS and Browser Requests
The API supports CORS (Cross-Origin Resource Sharing) for browser-based integrations. Allowed origins include your configured custom domains and localhost for development. All endpoints return appropriate CORS headers including Access-Control-Allow-Origin, Access-Control-Allow-Headers, and Access-Control-Allow-Methods. Preflight OPTIONS requests are handled automatically by the API Gateway.
Never expose your API key in client-side JavaScript code. For browser-based applications, use Cognito JWT authentication, which provides short-lived tokens that can be safely included in frontend code. API keys are intended for server-to-server integrations where the key can be stored securely as an environment variable.
Related Documentation
- Webhook Setup — Get push notifications instead of polling.
- Google Search Console — Connect Google data to the API.
- Security Overview — API security and encryption details.
About AI SEO Agents
Built on AWS with Claude AI, our platform automates SEO analysis, content generation, and WordPress publishing for sites worldwide. Trusted by agencies and businesses managing multi-site SEO at scale. See real results →