Topics API
Create and manage monitoring topics via REST. All endpoints require a Bearer API key.
Scope
These endpoints see only the topics created through the API. Topics you created in the AyeWatch app aren't returned by the list endpoint, and requesting one by ID returns 404. Updates for API-created topics are delivered by webhook — configure an endpoint or those updates have nowhere to go.
Topic types (auto-detected from name)
web_page— ifnameis a valid HTTP or HTTPS URL, AyeWatch monitors that specific page.subject— ifnameis plain text, AyeWatch monitors that keyword/subject across the internet.
| Method | Path | Description |
|---|---|---|
| POST | /api/v1/topics | Create a topic |
| GET | /api/v1/topics | List topics (paginated) |
| GET | /api/v1/topics/:id | Get a topic |
| PUT | /api/v1/topics/:id | Update a topic |
| DELETE | /api/v1/topics/:id | Delete a topic |
/api/v1/topicsCreate a new monitoring topic.
Active topics are limited by your plan's monitoring capacity. Accounts also have a default storage limit of 3,000 topics, counting every topic you have — active or paused, created through the API or in the app.
| Name | Type | Required | Description |
|---|---|---|---|
| name | string | Yes | A valid URL (e.g. "https://openai.com/news") to monitor a page, or plain text (e.g. "OpenAI announcements") to monitor a subject. Topic type is auto-detected. |
| interval | string | Yes | Check interval. One of: "0_5_hours", "1_hour", "6_hours", "12_hours", "1_day", "2_days", "3_5_days", "7_days", "14_days", "30_days", "182_days", "365_days". Your plan must unlock the interval you choose. |
| description | string | No | What should alert you. Describe the change you care about, e.g. "Tell me when a new AI model drops." |
| is_active | boolean | No | Whether to start monitoring immediately. Default: true. |
| verification_level | string | No | How much corroboration is required before you're alerted: "instant", "balanced", or "verified". Defaults to "instant" for pages and "balanced" for subjects. |
| triggers | array | No | Precise conditions to alert on, instead of relying on the description alone. See Triggers below. Max 4. |
Triggers (optional)
A trigger states a condition in structured form. When you supply them, AyeWatch still falls back to interpreting your description for anything the triggers don't cover.
entity— what is being watched, e.g. "GPT-5".attribute— the property of it, e.g. "price".op— one of<,<=,>,>=,=,changed,crossed_above,crossed_below.value— must be numeric for the comparison operators (everything exceptchanged).source_url— optional, restricts the trigger to one source.
curl -X POST https://ayewatch.ai/api/v1/topics \
-H "Authorization: Bearer aw_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "NVIDIA H100 pricing",
"interval": "6_hours",
"verification_level": "verified",
"triggers": [
{
"entity": "H100 80GB",
"attribute": "price",
"op": "<",
"value": 25000,
"value_type": "number"
}
]
}'curl -X POST https://ayewatch.ai/api/v1/topics \
-H "Authorization: Bearer aw_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "https://openai.com/news",
"interval": "1_hour"
}'curl -X POST https://ayewatch.ai/api/v1/topics \
-H "Authorization: Bearer aw_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "OpenAI product announcements",
"interval": "1_day"
}'{
"data": {
"id": 1042,
"name": "https://openai.com/news",
"description": null,
"is_active": true,
"interval": "1_hour",
"topic_type": "web_page",
"schedule_arn": "arn:aws:scheduler:...:schedule/default/topic-1042",
"next_run_at": null,
"created_at": "2026-08-03T12:00:00Z",
"schedule_status": "synced"
}
}About schedule_status
Returned on create, update, and delete. The topic itself is already saved when you get a 2xx — this field only tells you whether its monitoring schedule has finished being applied.
synced— the schedule is live. Nothing more to do.pending— the change is queued and will be applied automatically within a few minutes. This is not an error and does not need a retry; the topic is saved either way.
/api/v1/topicsList all API-created topics for the authenticated user, paginated.
| Name | Type | Required | Description |
|---|---|---|---|
| page | number | No | Page number. Default: 1. |
| page_size | number | No | Results per page. Max: 100. Default: 20. |
| is_active | boolean | No | Filter by active status. Pass "true" or "false". |
| interval | string | No | Filter by interval. One of: "1_hour", "6_hours", etc. Legacy values on older topics are also accepted as a filter. |
| created_after | string (ISO 8601) | No | Only topics created after this datetime. |
| created_before | string (ISO 8601) | No | Only topics created before this datetime. |
curl "https://ayewatch.ai/api/v1/topics?page=1&page_size=10&is_active=true" \
-H "Authorization: Bearer aw_live_YOUR_API_KEY"{
"data": [
{
"id": 1042,
"name": "https://openai.com/news",
"topic_type": "web_page",
"description": null,
"is_active": true,
"interval": "1_hour",
"schedule_arn": "arn:aws:scheduler:...:schedule/default/topic-1042",
"next_run_at": null,
"created_at": "2026-03-08T12:00:00Z"
}
],
"pagination": {
"page": 1,
"page_size": 10,
"has_more": false
}
}/api/v1/topics/:idRetrieve a single topic by ID.
curl https://ayewatch.ai/api/v1/topics/1042 \
-H "Authorization: Bearer aw_live_YOUR_API_KEY"{
"data": {
"id": 1042,
"name": "https://openai.com/news",
"topic_type": "web_page",
"description": null,
"is_active": true,
"interval": "1_hour",
"schedule_arn": "arn:aws:scheduler:...:schedule/default/topic-1042",
"next_run_at": null,
"created_at": "2026-03-08T12:00:00Z"
}
}/api/v1/topics/:idUpdate a topic. Send only the fields you want to change.
| Name | Type | Required | Description |
|---|---|---|---|
| name | string | No | New name or URL. Topic type is re-detected automatically. |
| description | string | No | New description. |
| interval | string | No | New check interval. One of: "1_hour", "6_hours", etc. Your plan must unlock the interval you choose. |
| is_active | boolean | No | Enable or disable the topic. |
| verification_level | string | No | New verification level: "instant", "balanced", or "verified". |
| triggers | array | No | Replaces the existing triggers. Send an empty array to clear them; omit the field to leave them untouched. |
The request must contain at least one of these fields. Unknown fields are rejected with a 400 rather than silently ignored.
curl -X PUT https://ayewatch.ai/api/v1/topics/1042 \
-H "Authorization: Bearer aw_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"interval": "6_hours", "is_active": false}'{
"data": {
"id": 1042,
"name": "https://openai.com/news",
"description": null,
"is_active": false,
"interval": "6_hours",
"topic_type": "web_page",
"schedule_arn": null,
"next_run_at": null,
"created_at": "2026-03-08T12:00:00Z",
"schedule_status": "synced"
}
}/api/v1/topics/:idPermanently delete a topic and its schedule. This action cannot be undone.
curl -X DELETE https://ayewatch.ai/api/v1/topics/1042 \
-H "Authorization: Bearer aw_live_YOUR_API_KEY"{
"data": {
"deleted": true,
"schedule_status": "synced"
}
}