-
-
Notifications
You must be signed in to change notification settings - Fork 2
Implementation Guide
This guide walks you through adding AWAS to a website—starting simple and scaling to advanced setups. You can implement AWAS incrementally without breaking existing UX or APIs.
Place a JSON file at /.well-known/ai-actions.json.
Minimal example:
{
"version": "1.0",
"name": "My Shop",
"description": "E-commerce storefront",
"baseUrl": "https://myshop.example",
"actions": [
{
"id": "search-products",
"name": "Search Products",
"description": "Search catalog by query",
"path": "/search",
"method": "GET",
"parameters": [
{ "name": "query", "type": "string", "required": true }
],
"result": { "type": "list", "selector": ".product-list", "itemSelector": ".product" }
}
]
}Serve it with Content-Type: application/json and enable CORS.
Add AWAS data attributes so agents can map parameters and results to UI elements.
<form action="/search" method="GET" data-awas-action="search-products">
<input type="text" name="q" placeholder="Search…" data-awas-param="query" />
<button type="submit">Search</button>
</form>
<div class="product-list" data-awas-result="search-products"></div>-
data-awas-actionmarks the form or trigger element for an action -
data-awas-parammaps an input to a manifest parameter -
data-awas-resultpoints to the result container
Fetch the manifest, then simulate the action using selectors.
const manifest = await fetch('/.well-known/ai-actions.json').then(r => r.json());
console.log(manifest.actions.map(a => a.id));- Inventory site flows: list the top 3 actions users perform (e.g., search, add-to-cart, checkout).
- Define actions in the manifest with unique
id,path,method, andparameters. - Map parameters to stable CSS selectors (
data-*preferred) in your HTML. - Describe results: container selector, item selector, and extracted properties.
- Add rate limits and authentication metadata if applicable.
- Publish the manifest under
/.well-known/ai-actions.jsonand set cache headers (e.g., 1h). - Validate the manifest with a JSON Schema validator.
- Run end-to-end tests that verify selectors and flows.
- Public (no auth): mark
authentication.required=false. - API Key: expose a docs URL and header name via
authentication.methods. - OAuth2: document token endpoint and scopes.
- Session Cookie: indicate login paths and CSRF requirements.
Example snippet:
{
"authentication": {
"required": true,
"methods": ["oauth2"],
"oauth2": {
"authorizationUrl": "https://auth.example/authorize",
"tokenUrl": "https://auth.example/token",
"scopes": ["catalog:read"]
}
}
}Serve the manifest and add CORS + caching.
import express from 'express';
import cors from 'cors';
const app = express();
app.use('/.well-known/ai-actions.json', cors(), (req, res) => {
res.set('Cache-Control', 'public, max-age=3600');
res.json(manifestObject);
});Add rate limiting per action:
import rateLimit from 'express-rate-limit';
const searchLimiter = rateLimit({ windowMs: 60_000, max: 20 });
app.get('/search', searchLimiter, searchHandler);from flask import Flask, jsonify, make_response
app = Flask(__name__)
@app.get('/.well-known/ai-actions.json')
def ai_actions():
resp = make_response(jsonify(MANIFEST))
resp.headers['Cache-Control'] = 'public, max-age=3600'
resp.headers['Access-Control-Allow-Origin'] = '*'
return resp- Phase 1: Document existing flows in the manifest. No backend changes.
- Phase 2: Add HTML annotations for stability of selectors.
- Phase 3: Tighten validation, add action-level rate limiting, and auth metadata.
- Phase 4: Add webhooks/callbacks for long-running tasks (e.g., exports).
Define optional parameters with enums and validation patterns to reduce agent trial-and-error. Keep variants additive, avoid breaking changes; deprecate with x-deprecated.
Expose pagination hints in result.pagination and support page, cursor, or offset params. Document next/prev selectors.
Prefer idempotency for POST actions using an Idempotency-Key header and 201/409 semantics.
Emit structured logs for agent actions with anonymization. Consider providing an /awas/metrics endpoint with action counts and 4xx/5xx rates.
Return consistent error payloads with machine-parseable codes and remediation tips. Surface throttling events via 429 and Retry-After.
- Add a schema check in CI using Ajv or Python
jsonschema. - Lint selectors against a representative DOM snapshot.
- Contract tests: headless run to exercise each action and assert properties present.
- Manifest published and cached
- Selectors stable and tested
- Rate limiting configured
- Auth flows documented
- Privacy and permissions reviewed
- Monitoring and alerts in place
- 404 on manifest: ensure path and server routing are correct
- Selector mismatch: re-check
data-awas-*attributes match manifest - Unexpected 401/403: validate token scope and CSRF config
- Pagination stalls: verify
nextButtonselector and disabled states